爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
/ C2 U! [. R5 y$ `! Y. W; K! q
6 X/ P9 _$ ~. B; F: k自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
6 w. c, ]+ n; |
7 s! x. s$ a0 c) Z. _+ c- I/ w速度优化问题真的很有意思啊。
3 |& x8 `. t  V+ `. ]( Q' F
* P8 G: }! I; y1 Q( r% b1 j3 B欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
; r5 _1 W( f$ D- P4 x$ v& l把代码贴上来看看?
: c4 T  b' z3 m: f
% t8 u' T9 U- i$ s. g* S" c难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
' u3 ?+ t6 n# b& w+ {$ _  e
数值分析 发表于 2022-9-24 23:04  J+ b7 A" _% ?5 s5 r+ T
拉下来?拉多少?
- M' M+ h1 q2 {* T+ R2 c7 v+ L' g6 X把代码贴上来看看?
9 t0 p# D" g! W, K+ d
" U$ r  P. b0 @% l* l' h, d( {
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)* _& j' @9 P9 `+ {
{
9 p3 X/ t/ V1 |* h# x# c        comp temp, xtimesy;
9 n& V# J' O: v        xtimesy.re = 0;
) X: Q/ N# z) I3 r% Z" z3 C        xtimesy.im = 0;
1 j8 L! v; L% x# N1 P$ Z% ?) \        int j0 = lenB - 1;+ e2 E/ ?9 ]4 M. u
        int    i, j, i1, reali;
* X' W  x$ ?2 @7 N        if (lenA % 2 == 1)! ]: f2 b+ y9 z0 Z
                reali = lenA + 1;
$ b% f- A7 G; C# c8 \+ a& o1 x+ |( v        else8 j, W8 Y+ X1 p1 l4 ~7 p7 m& a
                reali = lenA;
4 E0 O% N- R( Y3 [- ~3 P        reali /= 2;
) Y) q3 l/ p& o4 r* B% Q7 p
* d* }2 M0 G$ O4 p) ^5 s% \9 Z$ l        int nconv = reali + lenB;
. d- c9 n+ u# t9 N( U        //#pragma omp parallel for$ C* l# N" K2 A/ E: i
        for (i = reali; i < nconv; i++)- k3 ^: O2 m. g1 ]' S* Q4 x
        {0 I! ]  U4 y7 |% w- ?6 s/ U9 H
                temp.re = 0;
/ H+ q1 D1 c* O$ a                temp.im = 0;
" b1 ?- p7 A. @4 @* H                i1 = i;
% Y* T0 h: F: G: Z4 n                for (j = j0; j >= 0; j--)6 f, ]+ R% [% I- o, E7 i" W
                {3 `4 b/ o' Q# H; k& F) \; h
                        /* floating date operation */
4 e3 v; K. I+ x% L                }
/ v7 f+ W2 ]+ s( V
        }" }) N7 u' R0 t& b/ {
}3 Z( H6 Y9 d9 W

$ y3 U# ]( b$ _# `# h6 Uxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
3 s# U; X& J# B7 d' ]7 [  a5 ^* g0 _( Z6 p) S
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。+ G' \/ C4 S0 ?: u& f
现在call xcorr 100次,耗时78s.  G+ ?5 L, G4 T/ A4 X
- |9 v, X/ M2 m$ o
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
7 h- d, F" V$ g! b/ E; }9 g# ~; G* U, Y" B. b# E

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
6 }: C+ ]& |; Z3 \, B/ JMaybe Debug mode?

. E! h9 y# Q8 {. l1 [* l1 |9 X& ?- i8 f* y; N1 q* X' ?& v+ ~
不应该,看我上面的回复。
8 }: Q: }% f3 R  p# K6 b7 E3 B2 w/ j1 ?' ~) O. O/ z4 v
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
9 Q( g, {& x( R" i9 m/ g
雷达 发表于 2022-9-24 23:54
+ T5 X& }+ E8 @1 F5 o. ]4 \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# P: M3 c7 R5 c$ c& E) z, G. ?{; x9 }* k6 U: f
        comp temp, xtimesy;
4 N% o- g; N% V
7 y/ H1 S* o( Q% D& l) X7 z8 D
这个不是这么比的吧。。。
: X3 O+ @; b1 U' W6 Q4 ]& Y" G5 _
7 Z! x2 q# u9 u. o1 p您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
1 G/ n3 U/ T) C) o, |+ a1 w7 F& ^9 k/ `" s; n1 R) |
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
( Q$ o* c* x+ E% F
数值分析 发表于 2022-9-25 00:204 b5 l: e2 w2 A9 F6 M
这个不是这么比的吧。。。6 y& v/ w* C9 Z' E
5 ^' T7 J6 e: i4 z1 |2 x
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

8 w9 `2 C4 R8 z7 O5 H! B" q' }, ~" ~$ C; x
有道理。. x/ `* u: A" @+ `6 ~
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
) O! }4 Y9 S$ N" o6 H
3 w. _6 ?9 y& Y5 A我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
  Z1 [+ K1 O% M% y0 z! F7 [有道理。. I2 j0 K2 T% h; o2 I
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

: f' S3 |1 @5 y7 ^; T3 \- p% x; I  j你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
: ~9 y+ O9 q4 J, P) `Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20! g, G$ C8 k9 l* m; v/ @) O. h& V
这个不是这么比的吧。。。  V! M  i' X! H3 G& L3 a3 J

" E4 ]' P4 ^: E- A9 t" z您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

- H0 H4 v- n( w0 x9 `# @
8 R. f' Q2 x9 ?! _3 v$ U$ B现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 , i$ Z" Q' a6 f1 ]0 [( I1 _. o
沉宝 发表于 2022-9-25 01:48
3 ]8 t- m1 J6 O; P! c: J现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
# f$ T4 v2 K7 J0 M: d- I
5 r+ n7 ^! @5 S8 h
是的,兄台说的对。5 ]& c5 e: t( B; H" h9 ^

% Y3 S5 i; d* `6 J6 S& N6 e" _其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。# _! O4 j1 F0 x$ N8 c& _5 \* m5 S

3 P; X2 E6 C& h3 R雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。* e( o5 \" S9 L: I6 ?1 s
2 S& b* h& j* j. ]
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。" r% R# B1 Q; T  h; w
' [$ f2 {* M! G/ U( S
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
3 _2 L* U& t3 O( P. @
沉宝 发表于 2022-9-25 01:27
) H3 i1 ~' f5 @9 b, `你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
8 U; _6 b' \  A+ A) M' k$ E8 T1 p: Q
  K# n0 g/ ?' a; h1 o+ |  B
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。1 p$ V9 {7 p2 b8 I1 O; Q
$ U  O1 t% S8 `
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
4 O9 N# {" M  _/ Y. O* a6 N6 i( N又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

5 w& ~5 [& Q+ ~/ O时间差一倍的结果可以接受。
. ^/ P8 ]% a5 P! F1 y( y- k$ w* E
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ; q. \8 f. O- @
雷达 发表于 2022-9-25 04:47' F, _5 ^3 M: H+ p: B& v
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

3 p$ T9 {/ \4 o0 N/ A, r. i) h7 u+ `% z* X
7 L/ s( o* S, S- Z0 U) X! q7 m, u; X
; K6 r: `5 Y6 e# T8 W
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
# ?5 f( k7 q. [! I2 |2 _- ~/ c  p
数值分析 发表于 2022-9-25 14:58
3 T. o: Q& t- Z! q& W2 c# p: @) j能不能把这个也贴上来,看看和上一个有什么不同?

' `0 g* y# O( q# A" U( Q2 E理了理思路,重新做了一个测试。
/ H" g9 o1 y" ^/ O7 v$ \( V做了两个 vector 和 两个 float *, 都长 100000, `% i. u1 ]# U  X  P9 w. I8 J
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.* i1 y/ H8 n2 B$ M
. p3 g7 K4 M2 x- K# R+ |
内循环试了4种方法,
* C$ O% B2 b9 }4 s1. 直接调用 vector inner_product 247s
- X% B8 y1 q! U, E' ^: Y2. vector 循环点乘累加 237s
9 Q: P# \& Z2 s5 I: y. b# u( o3. float * 循环点乘累加 204s6 G5 H" H: T: x$ y
4. 空循环 100000 次 202s  Q/ ^0 g9 ~; ~7 G) b3 G5 M2 m
% p: e% k$ n; ?# c, ?
不做内循环 200s
7 {0 g+ A. c: o$ X
( j2 R; Z9 y0 R1 x你昨天说的对,内循环本身占比是很小的,大头在其他处理。, L2 X4 u" O' n9 z
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
- V4 B# \! z9 c! X1 r6 x2 N
- Q8 @: K% g3 q& o) ^1 A+ W% n至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)7 c( X0 C% I# f# Y! z

  h; p) ?/ t2 |3 m. I, x4 n(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
% o& I% x* P/ o6 k+ T: Z: J- F$ ^! N- f" r' F3 M, [0 L
        std::vector < float > vec1(N);) d3 H2 c! y9 n- h" Q4 |
        std::vector < float > vec2(N);. T+ d  `" @! t3 B: V
        float* b1 = new float[N];
( I" V( L' ]+ H& I        float* b2 = new float[N];- T& o5 M6 l  i/ p6 {" a
, [) O' R$ f9 T' W& B
        for (int j = 0; j < 6000; j++)
) l. y8 W! Q4 ^  M        {
7 V% U# D3 r' s( b2 l5 Z" b                std::generate(vec1.begin(), vec1.end(), []() {$ {  F( z4 [! ^) n! Y- Y: w( _
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;3 H) m. W8 e  y$ }
                        });4 b  ^4 M. |2 c7 K+ }: u8 M0 y* Y
' P4 J2 e' t" [" O4 L% e( ^: u
                std::generate(vec2.begin(), vec2.end(), []() {/ k' q4 R% p$ F+ f. |0 {
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
) K9 e  k9 V9 X& l3 Q6 s) W  P                        });& C. E* B4 i- Q
6 i( N3 ^' f0 _1 ]
                for (size_t jj = 0; jj < vec1.size(); jj++)
7 S- V9 b1 @. J* X" [+ `3 r' X" i                {
8 [0 {' r- z* |* H                        b1[jj] = vec1[jj];
: B0 n+ Z9 J6 d9 X                }
( v8 Z0 I& q9 D* A5 H$ p4 P0 }
$ }: f% I% `* x* b6 m                for (size_t jj = 0; jj < vec2.size(); jj++)
( _9 }4 R1 h2 z) d7 D0 R                {
7 ^5 m& _  V+ v( a; D3 Q) i                        b2[jj] = vec2[jj];- p# l' |6 n0 A; b) B' J0 x
                }- f$ X8 a) h% _6 ^
: ^6 Y9 w' p$ C% B3 Q
                //Method - 1  N=100000 247s  6 ^2 f5 H8 c+ E' s, A9 [1 |
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
" d# {2 G. {( o0 u6 S2 i                                
& M* v1 s& G# t# m                //Method - 2  N=100000  237s, L3 z3 B5 w1 c8 n- G$ j* D0 U
                /*4 ^* ^  [2 J+ Z/ S
                for (int jj = 0; jj < N ; jj++): k  F5 t6 p$ w" Q1 ~
                {) S" a9 Q; |* \7 P
                        fresult += vec1[jj] * vec2[jj];) V% S' X) W2 o4 W
                }
0 J, v- y* m" _                */
! p+ E# z: L, C( D; z                                
& r: L; m- P( C; z* a                //Method - 3  N=100000 204s2 Y, B2 |8 A$ ~  I6 r2 D
                /*
9 Y3 j; L4 b* n& l* ]! w                for (int jj = 0; jj < N; jj++)/ n# o% D: m) R9 h; {) y8 _& `
                {
2 ]( o& D! j# y1 C( F! L                        fresult += b1[jj] * b2[jj];9 L( `- m# S9 q7 G
                }/ {+ b4 Q8 K( n8 u! L. O
                */% \: {4 r+ k  S9 i0 V* O
- u2 p$ ^3 A* J
                //Method - 4   202s
: d$ P$ @. s8 A# t                /*; m# T6 a6 b: d9 j+ `* i
                for (int jj = 0; jj < N; jj++)
% S5 [% Y6 `/ j( ^                {' F: ~1 U4 @0 N" d, [6 P% a
                        0 ~% m: S6 c# ?3 ~* u5 F; o4 a! Q' _
                }
+ j! w, J, [& s% M# G2 f0 D" L) M: m                */
9 z; D3 v/ z& m9 W. O. h$ o                //comment out all methods, N=100000  202s               
6 s, A( W- g7 C7 R+ `2 u        }& w: E0 n" o" ?% z, V

! o4 p$ S4 j+ }6 E        delete []b1;
; k9 [6 _) G* O- }* w$ Z0 g; s        delete []b2;

2 F+ O9 z5 K' w% s3 s5 _/ T
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?0 H& _( J! m- t
3 ]) Z3 x  X7 r: e, }+ _3 [6 u
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?- m; @/ |  _6 k3 q/ ~8 L' z+ X6 @

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15( R& I6 H( n; q$ c) x4 d4 \/ ?, p
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?( J6 f+ H3 D+ H
+ A% l2 j. J6 X
你第二个试验里面的j在循环里面又重新定义 ...

4 g. \2 }! w8 N# ]- A- h% W内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
0 N' ^2 H2 e9 L- Y$ c; r8 ^
6 W- _0 I1 ?  }, b- t! _! }7 _不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
' r; c! X0 {/ b3 O6 F5 V内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
  L# ~+ C! h3 K* F! O8 W3 @# E' N; q; z6 c& O
不和它 ...
. T+ C" Z6 H& F4 A3 O1 @7 D2 ~
2 f) U9 s8 G, }7 ~: h
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。7 B, w: p1 {( o& h
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:540 }. Q8 T5 ^9 A4 [4 g) N" g( c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# H3 O4 q1 ]* U( S  @+ e{7 d3 t+ A7 _% y. _8 K- J
        comp temp, xtimesy;
% ?# w  b* h8 l) g
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。- r/ G) I& X: M" L( ]' v6 G: p; ]; b
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
* L: s: v5 s0 r* w, l. A, ^4 OVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:305 C; z0 f& L  }  ]1 ?+ k, W
理了理思路,重新做了一个测试。. c; E4 m% A+ m7 H$ Z
做了两个 vector 和 两个 float *, 都长 100000
/ j# f# Z& {* J- P1 f0 N4 z外循环 6000,里面先做随 ...

$ C5 x9 B9 R/ V/ y  w: e$ b* p; E这个时间是从哪里开始算的?
6 M; I4 S' u: [" J9 p4 x我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。  e! u8 ]- I% h3 Q) s8 D
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:392 r# d; ?# ]) ]. p8 ~
这个时间是从哪里开始算的?
1 d& u# d8 s# E4 _4 `- k我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& G* |1 u& W/ j6 d# H
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。' `5 n7 N! A( o6 W* _$ N
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。3 Q1 K/ L3 ?( f7 r: c- w
与此对应用数组(指针)花了2S
  L6 {3 M. g! e; K3 ?你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:546 W8 }! W, D" n' \+ Q7 ]6 @6 l- t$ U
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) g) D- ^. @3 M* v4 ]0 z{3 a( K, A) ]. g/ q: F6 }
        comp temp, xtimesy;

: v" Y: f: s) n% j2 _; v我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
4 B; P4 x; Z; ^% x0 ?1 n! r8 _- s& ~' E

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29- C, b0 N# H! \* P! s6 F
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗; c' ^5 I9 ^3 n  G
& x; P; L) T9 Q+ k0 j% u
...
: w5 e) b4 n9 _
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。. h' p, P% b$ U4 ?* D' V

, T- P* C" u* c% I9 K$ O雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 " u/ i" b; q6 ^- y. b$ s$ X' g

' X7 R. H2 _3 R4 ~! |$ I是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
' Y6 ^6 f5 \. s/ v$ V3 V有空时我会试试 SIMD和并行,看看能提高多少。
, W$ J: Z! S0 ^2 K' @2 l过去7、8 年没有正经用C++ 写过东西,没有 sense 了
% P! T, a; V, g6 L; O1 V: r) U谢谢大家的讨论,I learded a lot.  红包已发  % _0 B- \) L' t3 `* g
8 H# \5 E$ ]  l5 h5 U! ?7 W

; T" e+ R6 \7 \' r5 Y
8 y2 ~0 l$ i7 f7 T. {5 X( Y2 P1 H/ u! |- n: R$ u





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