爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
- ^$ _0 [3 |" j; E; x* R' e9 q
" J# I+ ^3 Y; U6 I自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
  Z# \* e: v3 e9 m5 z, l0 y' P% v* C! u
速度优化问题真的很有意思啊。
% x3 w' i  j; e' I" g% u) I" W" e# n5 H6 L+ O' V& H2 I
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?) o0 M9 h; G4 I% t0 e; V( N
把代码贴上来看看?) {  u% o  Y: H2 a3 B4 D2 y  c
9 V( b  A( \5 N% Z3 i% j
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
  G' E" L- l5 A( W0 r+ u
数值分析 发表于 2022-9-24 23:04
( k' K: e& Z' l& {拉下来?拉多少?  v/ l/ y0 ^$ n" `! |% |
把代码贴上来看看?
# `4 q! L2 j1 J7 G. J+ T( [& T! N& N% k

" L: l, X9 `: f: Q5 E! k, G0 ^void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 n- N* {& ?2 i4 _: Y" g
{- u7 |/ d3 @7 q7 y
        comp temp, xtimesy;4 p  ?' W$ t; c, q' R
        xtimesy.re = 0;6 f; F2 |$ q3 X- }# x
        xtimesy.im = 0;' V% Q! }% g0 C# a
        int j0 = lenB - 1;
5 m: F. w- w% }        int    i, j, i1, reali;% `' l! M, F- Q" s
        if (lenA % 2 == 1)
1 e. C/ ^3 F+ Z- K8 s                reali = lenA + 1;5 E5 p, `" v5 s, n# q+ l3 v
        else- N+ @8 n! F7 W7 ^: x. Z. D! U
                reali = lenA;
3 N: u# Z  Q: K1 Y+ z        reali /= 2;
# X, D. t' G, _% B; B5 x6 A
. l6 C% P- l8 p6 }' E# t        int nconv = reali + lenB;
, P! \' C5 M  y) ^) l        //#pragma omp parallel for( L6 t- E+ _# L1 g5 Z* [/ U
        for (i = reali; i < nconv; i++)8 e8 v; s) i! Q
        {
5 A, r; A$ e4 ^! t4 V                temp.re = 0;
0 i) Z4 `$ t1 z                temp.im = 0;
' X  I( T8 \, u# l& x+ \                i1 = i;
* O$ D. z- r% }8 I! V3 _9 G; F                for (j = j0; j >= 0; j--); \3 v  C- O9 t9 Y5 J* ]) g, M7 k6 z
                {$ O& t! `3 p) O$ |
                        /* floating date operation */7 C& @! ~1 B4 S! F5 w7 D
                }

% J6 k1 ~- E9 G+ Y( I        }
& C! v9 Y( @# k8 z# v: d}/ S9 ]6 E" W/ s$ Y8 J3 G

3 j1 W0 w; Z" _4 |9 d. j( lxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样9 Q1 q& s9 A) X5 ^% ]" j

8 ~8 l# T! f" T+ r; C# x) H. U红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。; k9 B% V2 w, V( l! Y* T
现在call xcorr 100次,耗时78s.
: b  W2 `% N3 o, S2 K
' m# Y" \4 Q& U' Z; q如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
( @; Z* a4 t: y" q" O
+ b9 I* l+ I; Z9 ]  m
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:338 Q, K& d# ^1 h" y+ D5 p8 Y
Maybe Debug mode?

* B, u; H# n4 d& P. A4 w
: X# g: ]" g- E8 B, r# I/ d; C不应该,看我上面的回复。: Q( d* B; C! Q% M
1 {" c: s5 [' |: `5 k& [8 Q. h
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
- Q6 k- q5 p; d: x9 k' o( Y
雷达 发表于 2022-9-24 23:54
' s. c/ t  T+ yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- _# ^$ y9 A! m/ Z; L{
/ \! ?! h; ~; S        comp temp, xtimesy;

  c+ [& p6 d; ]6 w( R6 s5 D/ M) F, O" I$ Q  D3 q
这个不是这么比的吧。。。0 R) B' U9 B6 ^

2 |8 g' ]" n% y! U$ S您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
- G% r6 \6 s6 l- z, q0 e: Q: h7 \+ F! U. W7 K2 x
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 + l: S" _& F& b" o1 g' R! S
数值分析 发表于 2022-9-25 00:20
5 o' a6 z3 n# @! k! n这个不是这么比的吧。。。6 I* F6 v1 {" o$ t

: W7 Y) y9 c8 N您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

1 K/ z6 f. }' K7 U7 V1 J9 f5 u' v8 d" k/ Z7 q
有道理。
- v' Y& B( K6 b& h+ W% T4 Y  B. N# x所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。+ ^* o& K0 u, I

. K) M; d  \) f我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:463 r' k: O' B$ L- r; U: g
有道理。
, b7 }; {' k8 J7 |& P. R所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

% w* s6 ^% W* P  L% p, {, u你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多% S, r+ t$ @1 c+ W* N( k  n
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
, Y# ]( N+ V4 z6 ]6 j这个不是这么比的吧。。。5 Y6 \( w4 u& w+ r  P% V: C

  c5 H1 U7 k- E% _; k您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

% }0 f; U: S1 |; E/ T. u, k% [: X
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
3 N; e$ }! ?* H3 v7 E+ g( b
沉宝 发表于 2022-9-25 01:48; e* c8 u0 ^/ y2 j& D" ?9 l. O
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
1 u$ S2 P* F2 I9 t. `! K" V# a
: u# r. Q. U3 z) @0 J
是的,兄台说的对。
  T& w. A! V" C( K2 D
4 Z2 y4 E0 n& W+ Z/ K* n) k0 f其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。+ Y; Y3 j5 D- T, w; j" h
6 T: V2 X, E( a4 a& ^. S
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。# s) K  l+ q& a2 o
+ I+ n$ I1 Q( J; L( X# o9 b; L
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。) s* i& T" J) y# V% B
8 z$ t. e" o* m, f; [$ ]: M
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ! m, k9 b8 s3 |: O
沉宝 发表于 2022-9-25 01:27
( Y- G9 w$ ^9 m) v* m9 W你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

5 _  f! ^8 m2 V: w% D2 q( k0 D. O, ~5 a/ m! C3 s  F
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。! Q' U  X+ C8 h
9 |7 E" N5 K3 v$ F' |4 `
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47$ q& `# e3 E! n, L& }
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

& ?) J8 }8 y3 w1 v* S( N6 V时间差一倍的结果可以接受。0 L8 F. Q1 f, O/ ?' c

0 N* T* K' W8 y你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 . f8 s2 {1 C, g0 k, H
雷达 发表于 2022-9-25 04:478 i5 A" b& |# \3 E3 C
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 h/ m+ e3 w0 n# z, l3 a
6 W( U; _) H. F
2 _3 `+ Y$ g2 C

% Q$ \2 C$ Y7 H& b能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ' {3 }6 u% V6 _4 w- i. T& z) F8 A
数值分析 发表于 2022-9-25 14:58
- z" Z! j* c. Y+ L. P! V. O7 E0 _. w. }/ Y能不能把这个也贴上来,看看和上一个有什么不同?
4 K" S0 G1 G8 ~6 Z: T2 ^
理了理思路,重新做了一个测试。
1 d$ t2 M- F4 `. {' C做了两个 vector 和 两个 float *, 都长 100000
5 x1 ?. I" v& f+ W% P, S外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! S0 ~. t" e3 ^# f/ P* J! S: d4 l5 W8 _$ P2 S9 s7 j
内循环试了4种方法,# S$ u! U+ T6 {+ _1 C* v
1. 直接调用 vector inner_product 247s
( c* s; d- F9 c, c0 A2. vector 循环点乘累加 237s: u7 j+ @3 t' l5 ^) ]0 m& r' n& [
3. float * 循环点乘累加 204s# y  [& |. D2 ]' k7 ^* M: E% ^
4. 空循环 100000 次 202s
) o! R  p- @7 x% R5 _& ?) K0 f! y) [0 B; G
不做内循环 200s
4 \: E3 C5 m# {% U; R' `
# o' N! w* W2 B) R- H你昨天说的对,内循环本身占比是很小的,大头在其他处理。1 f0 L) ]# A; Y( m. P
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。3 `) A2 j. ?& |! @

) v' ~7 G, O. u9 o3 A/ M6 n至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)+ \% _" |, h  X) r8 {" ~& H
2 O; ~* x: B0 m) g% R" k! p/ s
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
8 `) ]7 ]8 b" o4 q% }- e
/ T2 \1 T8 L9 [+ v* C
        std::vector < float > vec1(N);
' P0 w# `9 W8 i2 b) \# }3 @        std::vector < float > vec2(N);
8 _% e, y% z- L$ {3 L        float* b1 = new float[N];
6 w$ J+ K( t0 ~2 I) ~4 c3 y& l( y9 `3 [        float* b2 = new float[N];: x; z8 ~( B2 O' X7 Y7 \
; |2 K& L' `9 x$ R
        for (int j = 0; j < 6000; j++)
+ j$ m2 [: e) @1 W& w0 F        {+ V% h5 @& t! C4 o3 ]0 T
                std::generate(vec1.begin(), vec1.end(), []() {% J9 a1 h, I& j3 j+ f8 y
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
3 Z+ s3 `4 R, h. d7 E, g                        });
- u6 B, K$ p' F; J  H
# w% O0 D) {8 y                std::generate(vec2.begin(), vec2.end(), []() {
2 m+ ?  _8 {1 _! h7 x                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
% J% N& ^5 ]" C- u  R( T# K! [                        });' {+ Q* A- N2 {1 h& j) G8 r

6 L" h4 J* G* |                for (size_t jj = 0; jj < vec1.size(); jj++)' v: B* _; u8 c8 Q1 Y
                {( `# U% ]( X+ z2 q$ G
                        b1[jj] = vec1[jj];0 Q4 u/ z3 L" f2 D+ V( |- ^* p
                }( q+ D* U6 b2 p( v9 z( U, r
* I( U; l  x& L2 K' j
                for (size_t jj = 0; jj < vec2.size(); jj++)
/ n9 [4 y4 G  f* a9 N2 d3 _                {
+ L  H, D9 F7 d3 G2 ]! U) Y- t                        b2[jj] = vec2[jj];
8 L* Y+ s+ x  X) s$ G                }
$ H8 _- d8 m5 h9 Y4 n3 H% @
3 M8 G; i& z5 r                //Method - 1  N=100000 247s  
5 W. @5 v8 n" O* i* C                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
/ e% ~2 E1 ~1 s" M; i8 H# y                                
% ~" E2 W: k* e  T1 L                //Method - 2  N=100000  237s/ u' ?. p7 e* h% w6 i* t
                /*% Y/ x6 Z9 \- B7 e) m
                for (int jj = 0; jj < N ; jj++)
) Z5 a; ]6 I! r/ w0 X$ d2 w( D                {
8 ]& v1 T- e- y; I# V. v) W                        fresult += vec1[jj] * vec2[jj];; J6 f; Q, f! f9 L. H
                }8 J3 R0 p# e$ r9 N, N( ^2 s5 C
                */9 a/ I  P7 r* H$ Y3 B; [8 v( x# N
                                
) b7 \; ^0 s0 E                //Method - 3  N=100000 204s% D6 }( d3 l  U4 j) d
                /*
+ d5 z$ J8 d# C                for (int jj = 0; jj < N; jj++)2 K! W, z* W% k* L' R
                {
3 E: J8 E% y' ?; G3 ]                        fresult += b1[jj] * b2[jj];, b7 `) K3 M/ [0 R- `4 _2 w# r" X
                }
0 G6 N0 w& E. h                */
2 C, f2 \& l  q$ \4 Q" V$ B* F- m8 v1 M% I/ f5 Q
                //Method - 4   202s
: d4 ]2 Q! m1 Y; @                /*
' A8 d, H% Y3 m; u9 O& L3 i+ Q( V                for (int jj = 0; jj < N; jj++)2 A+ B* {" O" `! a$ L
                {
# ~; M1 `( _$ |3 ^3 n/ a                        8 o- B% {4 v# f1 }  h
                }
( ]) o5 l; H) ^                */
( u/ o" m" C8 n1 F                //comment out all methods, N=100000  202s                , f0 A; L5 N' L) a8 ~
        }
4 I, q: L+ |9 s2 O8 I! E, [9 o2 }( \( Q6 r& L
        delete []b1;% v  ?4 H) k! \8 C1 B' t
        delete []b2;
. |! e; ]% x; b5 C- u* q

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?- f, e( O! y( A: C

  G" p1 v' }$ ^你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?4 Q7 o- s& Q+ p4 A# ]/ q

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15, w7 P4 }0 c- |- ?# u! t
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
+ s9 C) O0 v% I+ c4 ^6 D. e
4 @& c) F. P) F* d你第二个试验里面的j在循环里面又重新定义 ...
# v* e( T  t/ X8 Q, q+ A
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
* a2 {5 i; u( k$ `# u5 A  ]& O
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
3 W; A, z+ @5 B8 e, @2 _- L内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) j& J3 J! k1 J
3 O9 t: N- X$ p' U$ j( s
不和它 ...

' {( |% X3 c% u0 a1 [# S/ }+ E' X  }. v6 |9 j9 ?7 a9 A* ^# y
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。; U& a+ `/ a* o+ ]
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54! l, b2 v. _+ w& J8 a- x6 H
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB); ?9 T5 t; {! x8 Z6 R9 y# B) H
{8 C8 `8 s4 n  f" K! y2 e" F& ^# I
        comp temp, xtimesy;
' ~2 n$ {  l7 `1 p- n* J
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。7 F; @/ o& Y8 z! p
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
! S+ Q' A- S: e: @% \) T7 }VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30. _, y' a3 }2 q6 O1 i
理了理思路,重新做了一个测试。7 g5 }) R) d. Z; @/ L0 \
做了两个 vector 和 两个 float *, 都长 1000007 C* {/ S; V3 e9 u7 t( T2 v+ O
外循环 6000,里面先做随 ...

6 U1 K6 E+ q" h, r' v这个时间是从哪里开始算的?
+ K( h& O+ j6 z) c- J" k7 O) [* H我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。' b7 k/ e& X, C! G" ?' W
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39% u3 e! ?$ y& f3 }" v
这个时间是从哪里开始算的?, k# K4 G0 D# Z$ d
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
9 B8 v; y7 e  v3 ~& }
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
' T4 t6 p+ Q  R$ O你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 U3 W+ j: U$ O7 G' o1 Y
与此对应用数组(指针)花了2S! W6 Y, b$ L$ r7 _  }! W, F4 b* I9 B7 W
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
% u& C9 {" _1 c5 p* yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)4 x$ }5 j1 \3 y+ }  z$ d
{
! _# v& n$ U' ]5 T$ I7 ^        comp temp, xtimesy;
/ X* u! w5 i( E" y5 T
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗9 c5 |1 s' U; H! |* ^- x! W
, w( g' Q+ o# P, z4 k" e/ ?) D

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
) V4 ~1 V& M# m1 A& q  R我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% w, X( {. |6 s. ]2 }& f
5 \! A2 q8 {- s3 s) \ ...
/ |3 Y6 Q2 T# s: g5 p
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。) }( w8 i, e$ n! \- h) D+ p5 ~, ?
9 P) @7 h2 ?6 O, A0 P* f* y/ `
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 & Z( e, b# F$ F5 F8 U- e) N8 `

" r$ r. f" J& H% d是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
$ }* F, X3 A: l0 N, d: s有空时我会试试 SIMD和并行,看看能提高多少。
* r2 v/ n. c1 K- f# v! l$ e过去7、8 年没有正经用C++ 写过东西,没有 sense 了
% I# u1 D* |2 l# }/ X4 @- Z谢谢大家的讨论,I learded a lot.  红包已发  
+ K, \. k( y$ [8 K# A5 I1 ]6 i5 }2 M3 I/ R$ D4 o
) U4 m  ^6 R: a* w: x7 l; q
% ^) _, I" {0 h9 \$ n
9 ~7 K! N  z1 {8 q4 T/ {' a9 t





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