爱吱声

标题: C++ 提速的新发现 [打印本页]

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
: }7 C3 ?4 i- q& k9 A/ Y: a7 _7 j; K$ q# w, r0 j; X# ~
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。0 n* s2 d! T1 c0 U* D# V3 i2 L# S
& K9 A% m9 r. b  X+ K
速度优化问题真的很有意思啊。: i% A5 d, T7 f2 k2 k0 S) O
/ }5 d" D4 `  ~9 k5 h
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?( T/ u+ j5 y+ o3 z" X
把代码贴上来看看?
3 p7 W  f. V1 f+ s
1 ~: x) A& v! }5 ]7 b难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
: _, ?6 Z6 m+ R1 E+ ^3 w
数值分析 发表于 2022-9-24 23:049 d# T. B1 D* @5 Z5 F9 J
拉下来?拉多少?/ J0 F2 ^7 h# `& ^/ U
把代码贴上来看看?

) z5 {( B2 w. C0 C8 [2 x
/ s7 ~! ?' Q  B3 J( hvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 F7 x. W: j$ J: r{
  |4 i5 V" K5 Y  k! y/ O% c/ @        comp temp, xtimesy;& b# M- k' ~" d1 K. X  b! c) L) C! C( ]
        xtimesy.re = 0;
# B9 ?) q" n( E" c, f# T        xtimesy.im = 0;
0 p$ C- ]0 `) h5 R# w6 d3 b        int j0 = lenB - 1;0 R8 x7 E* ~  H8 v$ \/ Q' `
        int    i, j, i1, reali;4 b: q% Q+ m* w% l6 g3 }
        if (lenA % 2 == 1)
  B& c' p2 [1 h, U" {                reali = lenA + 1;" K8 L9 J; M7 z. g! b
        else
( z# F% T) ^4 r- P6 U                reali = lenA;# @8 r  P5 \: F! I5 n  o
        reali /= 2;
' \: E% _' p1 o# Z6 I4 i$ }& u* i9 q7 r/ l
        int nconv = reali + lenB;
: \% K+ K) F, C- ?        //#pragma omp parallel for6 O  q, u* S5 z6 n8 l
        for (i = reali; i < nconv; i++)5 Z8 p; L+ q2 [/ [- Z
        {; Q  `# S* J, b
                temp.re = 0;
! L. m$ b& O$ `5 E. x0 t                temp.im = 0;
" u% S4 d0 [9 Y" G' c% G                i1 = i;
( m% u) g" z* h* Z7 d                for (j = j0; j >= 0; j--)# T9 P1 h3 d+ r' K' C% Y
                {
' B4 l9 f0 V) A' J! r$ y9 P7 }                        /* floating date operation */3 F" }) t+ R( ?: g
                }
1 G- K7 ?9 C2 n( b- ]! v
        }4 F7 s# w1 N- f$ p) W; P* S
}
- B* ?4 k  m5 n- A' X
8 ^. F4 `5 H( excorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样$ ~3 Q' b. Y' F* q2 {
; n8 ?; ]( h/ U# ]! P  a( i) J
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
* @  ^7 ^7 m) D- D. M/ M现在call xcorr 100次,耗时78s.
" S9 {% _" k8 f1 b. f! [6 d$ D7 V4 [% {# R
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
% \% E$ L" a; y" Q9 v7 l
8 k" u3 h" O; `; Q
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
7 \. {7 Q8 w7 `- K! ?% \  u- G/ QMaybe Debug mode?

0 V( Y* e, ?0 C4 b/ g1 z* |7 _% }" A2 Q2 U- T) y2 R
不应该,看我上面的回复。/ [$ x. D1 r4 ~2 ]! S+ t2 O
3 B' \: u0 r$ x- x8 T
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
5 }2 z4 h) T& c- b$ _: {. g
雷达 发表于 2022-9-24 23:54
3 v- p2 D# c4 O) O, {void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  P0 L7 E$ I- W! q# P  i& ~0 L+ ?{
3 P4 ^7 H# y4 I! x% `        comp temp, xtimesy;
) O; l- Q1 M6 _  S  c4 g+ V& `
4 }, ^% r3 y1 A8 H! R( Z
这个不是这么比的吧。。。
, e( W0 N: P% o9 ?; P4 _' I/ ?1 I
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
# J$ u( W5 U) H5 O* \/ b6 s3 c3 J) f  H$ J" z& g- R2 h
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 2 P0 c; R, O9 s7 W1 i1 j7 z1 `; L9 x# U
数值分析 发表于 2022-9-25 00:20
) S  `- _7 l! |这个不是这么比的吧。。。
4 H% `8 n, |5 c" D5 x! n$ O' o) o, Y" k* M+ @4 D% d" a+ \
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

$ {: \2 U3 H" Y0 a; \, C
4 Z- w  f8 J( M$ A有道理。; I+ ~' o5 [4 ^! h% \
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
' V- q1 s+ V% D( x( _9 h5 t, U5 n7 V% \2 j& E/ p" M
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
( o3 ]1 F# I& V% F7 A; @  a有道理。
- D! D; s1 ?' K; y0 N所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
  h, p& m6 j! b. g5 k! X9 L
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多# C+ k( E" o# B+ d( d" m
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20& h& c' }) ~+ X
这个不是这么比的吧。。。
- a$ F+ N! n# o$ w. C9 P' t7 |  h( m& t8 U
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

) O# I0 Q, T1 a, S) F$ e( i
2 {' S5 f. x  k* E) H' c  R现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
* G( F; n5 _( {8 a" C
沉宝 发表于 2022-9-25 01:48
% Z& V' s) t5 ?7 I9 P- C/ J现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

# U9 g6 I8 ?: d, z% t4 _; U  x
6 d- S4 p4 p: q* q1 @& t% U是的,兄台说的对。9 b+ B$ t8 S' L

9 Z8 q6 P/ b8 ^4 \% e4 G/ ]; S其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。5 T4 }) b1 y! R$ ]8 P0 G9 V
% ]9 K* R& X6 G. k$ [
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。; S1 o  Y( l* ~; ^) e3 r3 s
9 g2 Z) _& ?/ z+ q8 [5 I3 s
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。: b5 O/ S& o" V6 B

( R9 `9 t4 c4 v' u3 @当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 , H4 e" Q  [' E" U+ ~. C
沉宝 发表于 2022-9-25 01:27
; ?+ P  j8 D0 d; s* i! I! H你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

2 x- ^- s0 P1 g3 n6 r; |% V1 G: p
  w$ m$ z  C, R. J: A& ]又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。; M+ U2 x  M/ @! }
0 p; w9 V: C% j, L2 L0 b
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:472 M( H1 E2 {$ V, _. W/ L
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
, o  [3 e& Y4 D3 N
时间差一倍的结果可以接受。: p  }- y6 q3 L3 n
6 u9 _- d* a. Q' m+ }7 {, L6 U
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 4 g3 w8 @& k, Y
雷达 发表于 2022-9-25 04:47
7 O& o% R2 f- j: L2 B+ j又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) h/ O: U: t. g2 o
7 X( z% r0 e" l( M) T

; g& r2 k4 J% _& C" s) h6 l8 K5 ?2 r, d+ z- J) a3 Z% e
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 4 }5 A* B" W+ S8 o  F
数值分析 发表于 2022-9-25 14:58# Y, T4 Y6 E: Z( K2 t. N9 s& B4 |
能不能把这个也贴上来,看看和上一个有什么不同?
3 z6 k9 M! @$ _8 U$ B1 K% y
理了理思路,重新做了一个测试。7 J0 a4 P- t/ b) Z" d2 m! g6 O. ?" V
做了两个 vector 和 两个 float *, 都长 1000004 k/ @3 o( q6 ?( C- F* a7 {
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
6 M) `1 J/ H) T- J/ [7 t( h
9 ?( T9 v' q5 {4 M7 m内循环试了4种方法,$ J- Q. Y; Z( t6 q4 d3 r' l. K
1. 直接调用 vector inner_product 247s # M# g% {3 @/ A: w
2. vector 循环点乘累加 237s
- Q7 s) k: ]/ K1 k4 _% @3. float * 循环点乘累加 204s
& Z4 l6 T: p5 k; v9 V, y4. 空循环 100000 次 202s7 o4 @- P! I2 j( j7 V4 t. O
% X& H2 I7 g1 P- ?5 i) A
不做内循环 200s: q" l2 H3 J8 U2 w5 Y0 G  X

2 m5 m5 t9 G( x: y: z+ @, W你昨天说的对,内循环本身占比是很小的,大头在其他处理。
2 n- `4 d# D1 I  Y另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。; t% {6 q8 @2 }* Y
8 \. U( J# I# G7 \* w- r  i. ^6 {; F
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)# j8 K2 ?2 r4 ~; _3 Y+ j
# C+ m' u# L1 B* s5 k
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
( Q9 \0 N& X4 W9 ~7 k+ ~" H/ b! L$ }+ p
        std::vector < float > vec1(N);
! {. q* k% g; j$ j  ^6 ~" K        std::vector < float > vec2(N);
' t, c0 W' f$ i7 b) E7 E1 g9 T1 G        float* b1 = new float[N];  ]4 f/ m( Q1 H, [, F
        float* b2 = new float[N];$ W4 `3 J8 {' V5 ?$ T; q
; V# \9 w7 t' h! I6 X; O. U
        for (int j = 0; j < 6000; j++)
1 A* h* f2 u6 b3 V( a, J/ d, `        {/ a1 X9 n2 e& q) h; y, y; w' L
                std::generate(vec1.begin(), vec1.end(), []() {
1 C2 n8 q/ x- V" C& X! ]" f                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;& v- f) f5 N* @/ ~/ z
                        });
' b; D1 [# _% j6 q5 W0 i' N6 P( W+ t+ Q3 z
                std::generate(vec2.begin(), vec2.end(), []() {
9 b# a. Y6 U2 }( l( u$ c/ |0 j                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;- @$ S. w0 u3 [" O
                        });
  W5 O) ?. `% F
  C  V9 }, d- h4 ?" u, v% U4 x                for (size_t jj = 0; jj < vec1.size(); jj++)
$ ]* y+ ~/ ?& F5 u' d                {* P$ R. V! D; u2 u  {) T7 f+ Y. c7 y
                        b1[jj] = vec1[jj];. Z" u4 o& J" n
                }; N- u3 \& W) e: M& H5 T; P
4 ~  d0 Y- k4 }  C
                for (size_t jj = 0; jj < vec2.size(); jj++)4 t1 f; L% U% l
                {
' N8 j" U# {' l* Z1 h2 E0 A                        b2[jj] = vec2[jj];
1 b) m1 }/ {1 o0 l# F( g2 A) _. m                }
9 g8 ^/ s" ^" p6 R4 f( u- G6 Z% J8 v; i, Z2 x- g2 K
                //Method - 1  N=100000 247s  
5 P! a( D7 k0 l9 l7 o                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
/ V% M. {: |- J" m                                # V4 g& @  a+ k, b
                //Method - 2  N=100000  237s7 x$ \  s: [, h: y& T* T) x- }; a; v
                /*
( u0 k' l; w* ?                for (int jj = 0; jj < N ; jj++)
9 R0 ^& C; y( o                {
% i- L' z* \( v# S* F+ V' j, X  |                        fresult += vec1[jj] * vec2[jj];
: N( I. L0 `" K6 N) `5 j. p                }. H" b# G- R5 F" c! Y; d5 e
                */
3 k% w8 Q4 m  I& [                                & |& L7 a" g, f1 A: v
                //Method - 3  N=100000 204s& A; [" i& ]/ p0 j8 |
                /*0 T1 O% n. e# v) ~% o
                for (int jj = 0; jj < N; jj++)
% ?% v5 b8 I' z, S* L9 }                {
  \* c4 M8 u+ j' g) q! A                        fresult += b1[jj] * b2[jj];
  e6 b/ J! M- F2 x" {! Y3 e                }# E- [; O! z" z- D; ^
                */0 U$ m5 `" {6 Z  r# V7 n

% J8 D9 B. `; H; S" ^: x( f                //Method - 4   202s
7 u/ O& T+ g( K, z6 Y9 `                /*7 b6 t  N" T% s% L0 Y
                for (int jj = 0; jj < N; jj++)) o8 A3 P+ X8 K7 K6 z( {' J
                {
( D7 j: S! W9 |5 c) ^                        
6 T9 D- [4 h! v" I/ l+ I                }
. A6 Q. F/ Q: D: |3 q1 p2 m                */
+ _% E: z6 S4 e2 v                //comment out all methods, N=100000  202s               
! N# p$ ~5 I; N        }' n+ T! V1 h, ~; X' C% u

( |. ]" j3 I) ?/ V, \7 j/ W, J        delete []b1;2 Q, H' h+ T: M  A' B1 o
        delete []b2;

1 l9 @+ K, l; t+ g3 `
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?/ L6 H" @. g# T  w, z1 Q0 D
, N0 A9 I& C' a, z# u1 H/ M
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
* [# y/ K' b" B/ q
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:157 O* B0 v+ s% j7 N! {( ~
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?6 C; z9 t  v4 I" t

6 w( }+ ~$ k) u* y你第二个试验里面的j在循环里面又重新定义 ...
  W& _0 P; c6 I" d9 w
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
! g9 t& C/ O6 U. A' Z; D; `) c1 t8 I( q% A: a( c
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:165 E% s% n0 p1 A& c. d6 O- x
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL9 J- N- i+ F( O8 J7 ~, E* S# l
" [& S8 B  D) Z% y4 D7 Q
不和它 ...
/ C; \' B; b  \; w7 B' X
6 w2 L# X+ {9 d1 F% F. o6 L; K
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
, S' N% a& `+ i  Q9 u5 |0 ?后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54+ h' h$ a7 h# V4 T+ m4 J
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ _3 N- A% s% N+ Z8 h; k
{( w. e, Z5 o7 |  L+ ]! _8 I! }% |
        comp temp, xtimesy;
! ~& H3 u; X# O1 m- |
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
; y; S+ j( Q* r5 i% p内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?7 W# [+ P- c) }
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
2 z1 q; s3 u3 z, \理了理思路,重新做了一个测试。6 f) h* j/ Q. E* v$ j
做了两个 vector 和 两个 float *, 都长 100000
! f8 E, p& g+ }外循环 6000,里面先做随 ...

& n+ o7 q: V. J* m" o这个时间是从哪里开始算的?8 J5 @( r/ b3 E6 Z0 L
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
, T/ a0 N2 U! z5 P* \1 K/ q按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
2 `# f( `2 \' k3 h7 N) |这个时间是从哪里开始算的?# `& J& y( M  P: m! c2 q- u
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

. X  W3 |! F4 r* w6 ?# v, {) q我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
3 o: K# @  T1 m& a' V你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
% J! f. s/ A1 s5 y* B5 T与此对应用数组(指针)花了2S* z9 Y. S8 n. |! Z; \& c
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
& D! \& F! B$ C  O8 v# K' ^, Uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) ]" j* b& }2 ?& d1 s3 y; n
{
6 a3 x- r" l! T        comp temp, xtimesy;

% Y$ A% L6 I3 `9 Q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗* y8 z# q1 m. |) ^- q
: T+ s/ P* W* a$ e7 z" M7 `3 g

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
8 e$ [; X5 y0 Y# P3 n" t% q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗6 Q8 s2 G5 Q! a  \( \2 Y
5 [% B8 o: k. w' {- ]
...

) w  s( ^+ W3 P! g% g6 z9 C你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
/ `) o! Y' u2 q( Q$ e( o( a8 S3 n3 v" f  O0 u1 H
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 - L" Y/ ^8 H( B( b6 {

* Z' l/ C1 Q6 N' D: H3 n是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
  d! Y8 e$ Z  b$ r* U9 H- A有空时我会试试 SIMD和并行,看看能提高多少。' V  X" c! p: ~! t  f& ]
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 & Y1 ^( v& f! m5 ~9 U$ W
谢谢大家的讨论,I learded a lot.  红包已发  7 S! J4 k# f8 a* e, q( a4 P
2 q: k# B3 Z0 Y+ L; F: {5 [/ o# G
+ k7 o+ I& Y" r. f9 {! a

: @! P% m2 r8 G. l' f6 f
4 ^2 T$ ~  t) b' L9 Q% x




欢迎光临 爱吱声 (http://129.226.69.186/bbs/) Powered by Discuz! X3.2