爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
/ }0 ~5 ?1 i# W
( d& r* W+ b0 E) O- c( H自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
) W9 v& D2 e4 U% l3 F, }9 ~3 H; H* _3 r4 W. _7 o2 u
速度优化问题真的很有意思啊。" @! ?! c; a' y
# }# @, V. m7 D
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
* q1 |- _+ L, h7 [. H把代码贴上来看看?
0 w$ ~: _4 M2 y- L
& R) g% W' S) q# ]难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 3 k! S, W  E  z& n+ V2 _% d+ c/ c
数值分析 发表于 2022-9-24 23:04
5 r$ ?7 a0 A! U拉下来?拉多少?
- A0 p3 v5 N* F4 V5 o& g- H把代码贴上来看看?
/ [9 d: H6 o0 {; O# T

: b4 ^9 Q. C1 s- ^7 W( X3 v2 ivoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' r6 \1 W2 u: N, b8 [{' x3 F9 K/ `! E  N
        comp temp, xtimesy;, _, k+ i+ P% u9 y/ N2 l
        xtimesy.re = 0;7 W" ]5 q- M  I2 |( n
        xtimesy.im = 0;, w" g) P+ f- O$ f  ^
        int j0 = lenB - 1;
: j& m& O8 P' l8 i# g) B        int    i, j, i1, reali;
9 g* h# M' }6 U! z" V6 i4 y        if (lenA % 2 == 1)6 ~; d5 E9 e) n( @
                reali = lenA + 1;
# w) Q+ t9 O/ Y: w/ @        else6 K3 N& o* Y7 o3 x- a; ~! P
                reali = lenA;  G, K1 @( @; I
        reali /= 2;% T" N7 m* T: N3 U6 o5 @& U
9 S9 A9 t' X, W# B* p2 r( c' `
        int nconv = reali + lenB;4 M  I* z, w; `4 _# j3 S
        //#pragma omp parallel for
: z0 a2 r7 `& H        for (i = reali; i < nconv; i++)& C4 t! m- U# }8 N7 K
        {
) [# F! Z( K! _1 w: M$ A                temp.re = 0;
/ M& @! t* b& Q  T2 d1 X5 S. m                temp.im = 0;
& L9 \1 w- w# k- c- h& W: Y                i1 = i;
- T" o7 F' T8 Y                for (j = j0; j >= 0; j--)
) L2 c' |4 L  H" x. d7 b  ]  \  [                {
$ k( F6 J* x- o$ l! d2 L# u+ R                        /* floating date operation */
; X- a  X* P* y* _# H( L& b9 O                }

1 l4 \5 I! l  l9 r+ ?        }
' _, N2 k0 U7 Y6 |/ Z) Z}
/ p$ {; W$ s3 C* I+ x% z% R: Z: b- }/ {; V) G4 p7 T
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样4 ?, o: X  @0 H; x
/ j  P2 q( l* @& |; D' |1 ~% O4 v
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
4 Z8 v& h4 o; |, ~: I& W现在call xcorr 100次,耗时78s.
% ^: B! C$ ~- x: X3 h( \5 ]4 O$ b% D4 p9 K5 t3 v, z
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ; z+ X4 E+ F" O$ d5 r
6 |- d3 J$ c; [! Q/ b

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
+ V0 W! }/ R2 P# |* w" X$ n' GMaybe Debug mode?
0 {4 t0 {$ f. W9 K7 ]

6 \* e1 s2 A) a不应该,看我上面的回复。$ P2 a/ w, P" Y6 W# J7 H  D/ i6 H
% @. [, a5 _; p
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
1 u) X$ \, g/ N" s; r: q
雷达 发表于 2022-9-24 23:54
  s7 ~$ g# P# D% y/ x3 Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)  b6 l% K7 U0 Q6 ~$ e
{
7 u; X5 e, d* s' H: r        comp temp, xtimesy;
$ k8 t7 _, I) c6 Y# o5 d( f0 w

1 V5 x) k9 e5 }9 b8 ]这个不是这么比的吧。。。
8 n* a9 j1 K: N# D9 T. k7 s1 K/ b4 P( d6 H
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
3 \* G  m7 z4 c" z0 I; x/ q
/ {% n" s3 I: G; H4 A而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 8 J0 ~* Z# S9 B, _+ m  v' b+ \
数值分析 发表于 2022-9-25 00:20
1 E4 v5 e4 X4 L" I; g* P这个不是这么比的吧。。。
; t% m  s, w( R2 e
0 C  |, R. D7 L7 C$ m您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

; r  a% d5 l3 r0 h
6 P! G% q5 B4 Y" }! M& }- M有道理。) b* M( `6 i4 h4 k. T
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。6 U, N  R8 R! N* n$ ~! u% i* P5 `% f
* V( X& ?. p/ ]6 K
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
$ w" ?8 \% [: {- |5 K7 o/ B% ^! ]% w有道理。, n- V4 O: X  ?, r& ]$ L0 E& f% ~8 u
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
& G  z8 V$ h5 R- m* ^1 w
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
, u3 {. L7 P7 r2 [6 XWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
: n) v6 L8 L3 I. }这个不是这么比的吧。。。1 _1 w! p, m- W& q1 Y

& v9 G! \* G2 Y$ o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

. N' H8 p' F& B2 _+ W" n  E+ y9 U( s6 ]" Q( w0 t
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 8 U. i5 O1 j5 ]9 l- h( r) b
沉宝 发表于 2022-9-25 01:48( Q2 R" Z' Z9 I9 n% [
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

+ v/ ], P) ^2 t; ]) k% _& a
5 z+ [, s0 {8 K' `+ ~是的,兄台说的对。0 ?. `, C! T$ K. T

" \4 b( d6 Y' ^其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
, L5 C- J+ E( M& s
8 i/ u$ D. t; M. D+ \* g: b# g% S% G雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
- ]( N3 T* d$ X9 X# n+ Y% j1 ]9 }/ \$ O
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。3 u+ w2 t; U1 I- U; M

% e/ X6 P9 }5 |8 r' V6 Z当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
' a3 W" U: S$ J# A7 C8 s  E
沉宝 发表于 2022-9-25 01:27& h8 {: N' g! I; H3 I# q+ k
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
+ J# U3 |1 i$ f- W6 t, f' B

7 ?3 V0 {& |( f: \又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
1 v, T9 i% @- b* d3 d/ e
3 o6 B( P6 V( j: ]) k/ _& a我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
% D0 i; x% c0 k6 x又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

0 R- \8 H1 D  }: _时间差一倍的结果可以接受。7 a. [% B3 d0 F" h5 S- `( }8 d

# z3 g6 Y/ K; }, l+ F你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
# c( A5 {2 I  s+ h" Z
雷达 发表于 2022-9-25 04:47
( B) N% v1 ~- W9 S又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
' O) Q% C4 e: u2 t7 j) m- Z8 d4 }
  i$ [  l5 \3 O6 r( T; t

& ]+ O% w: ]( |7 i+ Y
& Y% s0 i0 `6 H/ i+ q能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 : j. r5 }9 a; a, l3 Y4 G+ {# c
数值分析 发表于 2022-9-25 14:58
: |1 k( D3 A# p* d9 S能不能把这个也贴上来,看看和上一个有什么不同?

1 Y2 `* h; [/ D5 k理了理思路,重新做了一个测试。' w' \! e- |. G
做了两个 vector 和 两个 float *, 都长 1000002 }( J) t8 Q! m( V( e  F+ P. D1 F; X
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.% f/ k" ?4 Z. B! d  B
4 g' ]+ {1 v8 R( `9 ~8 o% f- C
内循环试了4种方法,
( b" ^* d" ]& v- |, O4 \1. 直接调用 vector inner_product 247s & o7 E$ ^0 d- j$ `# w. z
2. vector 循环点乘累加 237s
( i) a9 |7 N$ a7 f2 @4 @- Q0 s3. float * 循环点乘累加 204s
% C) [; e4 u$ ]( \6 J6 t4. 空循环 100000 次 202s" e  V% s0 x6 X! p5 g6 K
! s) Y% k& v: s* w! k
不做内循环 200s5 ?. h' S& P1 g! C

! p4 u7 U6 x5 g" u4 U, a3 k你昨天说的对,内循环本身占比是很小的,大头在其他处理。" [4 a1 ~: ]5 `) {
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
, B( h- |- R" c% \$ R" _  c; v4 W0 p# ~& b
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
2 B8 c' B$ q* ^9 P
2 q" ^% j0 r& a6 I$ X7 A6 M% e$ ^(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)* \% ?4 n2 R+ n7 C' ?& c9 b
9 ~/ S0 R2 t: |! K' c
        std::vector < float > vec1(N);
* r' Z; Y& |( W3 V0 K, J& _        std::vector < float > vec2(N);- |2 g* [( q: V. V6 F- j8 {
        float* b1 = new float[N];) l9 ?7 M2 W6 h8 C  Y# R' y% M3 ?
        float* b2 = new float[N];7 V- r, E0 X6 |* p9 x2 Z

. C- D! F. z0 c8 j# G( j0 v1 d        for (int j = 0; j < 6000; j++)
! H1 ^0 c# v# I2 F% Q        {
" K9 r. e8 g% {! D% J                std::generate(vec1.begin(), vec1.end(), []() {3 w7 T4 C7 H2 T+ `/ T
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
. q& `7 ^3 m# w                        });7 L9 z7 A* }1 V

3 T+ p9 S" u) S9 y- O                std::generate(vec2.begin(), vec2.end(), []() {
4 l3 C1 T6 n* e2 ^                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;0 ~. B3 p1 U+ h, p' y2 `. ~- V
                        });
! T8 _$ G! r- D0 {0 S& `. f% U" \1 i' i
                for (size_t jj = 0; jj < vec1.size(); jj++)
" X7 K( _5 R9 z' Q: R" e; Z                {
; [- U' K: l# x1 P/ \                        b1[jj] = vec1[jj];: r' r* D/ N! A7 d; K  @7 C
                }
. B8 b. O, ~  H
: ?" m) T! f9 r% M( D# Y3 u8 X                for (size_t jj = 0; jj < vec2.size(); jj++)" I) s; b% N  K3 c
                {0 L( o% @5 U( K/ q: V9 Z/ ?- U
                        b2[jj] = vec2[jj];4 p5 e* V+ Q. A# M, |1 V
                }
' H! j5 g) g4 o8 ?
3 ?5 U+ _' y/ p* \                //Method - 1  N=100000 247s  
# z6 d* m4 \* B& ~1 z) ^                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
! X1 [; n$ u' _6 t                                
% r' {- Q3 E+ k+ e3 Q, o* w; s/ \3 ^                //Method - 2  N=100000  237s
2 R4 A: `4 Z7 ~' ^7 o6 c                /*
9 l3 `+ u' }1 f3 s6 j5 x/ T3 D3 l2 o                for (int jj = 0; jj < N ; jj++)) m" j5 m) ]6 d) \
                {
( K( j$ w9 o, P' t                        fresult += vec1[jj] * vec2[jj];
! Y/ s. \# J" g, K, e                }& }+ f# B! @8 P2 x& w9 H
                */
0 b9 l6 [. E  v0 ^4 B" k                                $ d* e8 t% x7 P+ ^( R0 C
                //Method - 3  N=100000 204s
4 B/ p; Y( z$ M0 ^9 X/ W                /*& \; M* }2 N: y$ l: r
                for (int jj = 0; jj < N; jj++); I6 e! I; [, \+ t" b
                {
; R1 S# l7 _# G6 @                        fresult += b1[jj] * b2[jj];
  S- A: P2 x5 m' K, H; f! O                }( X% Q& D  V9 `  D* s
                */
  c& u) T, V# ^1 M
, f1 O' X2 U! i) i- T+ S7 B6 v2 T                //Method - 4   202s
6 Q8 j# Q4 Y4 e; W; r, [7 f                /*
+ [5 n4 F4 D. g                for (int jj = 0; jj < N; jj++)* W* T) {! _6 o  q5 j/ {# R
                {+ }$ t: n" W& b% G0 R* f
                        . Y$ ~, _1 V1 O' F" J
                }) q& w" {" h% }: B
                */
' L9 ~1 C+ d; o                //comment out all methods, N=100000  202s                5 g8 J6 @+ X' a
        }; ^* g( A' F  r" B, i7 r  Q9 R# @

3 }9 l* Q- o8 `        delete []b1;
  G8 I0 K  }; l# ?# T        delete []b2;
! }" Z8 e3 R" r* Q, J3 x5 ^" b

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?3 \) V5 {" `. {9 G" x
9 j) P  X3 _8 {% A3 w. L: e
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?; y! }4 u5 X! d0 _: q; {7 X

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15- z, j9 D4 {3 s- y/ [3 e. J
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?# n, u" e; t- W& {
% G. o- ~2 D$ X$ \+ a. j
你第二个试验里面的j在循环里面又重新定义 ...

9 V: ]' j2 |! [* M6 f$ B& C0 w( r9 ^内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
2 {) F' {- ]5 w$ X' p+ O( h7 t4 N9 [3 f" u
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16! u% s7 W) T, X% Z8 ?( f
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL* s4 S# G+ c  Y

! c  l0 ?: ?* i! C% _- ?不和它 ...
0 g% o2 R. G' l
4 w: Z5 Y$ R2 a1 v! Q- l
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
* R1 _9 A2 j+ W# @! J6 b0 S后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
1 l0 x. q) K/ {* z) x% o9 [( _0 M- Rvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
. u+ R. [- }+ }; H% n" E{1 {1 \/ D7 h% v& A' s5 i
        comp temp, xtimesy;

/ d& a* e8 U* \4 ?- s这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
( W0 E* t/ e/ Q. Z) Q, J6 ]" w2 J& R( J内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?% H& n% Z, K7 _9 R9 e6 g( \
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30" z2 i$ r  h1 T
理了理思路,重新做了一个测试。
8 h8 o( V6 U% C做了两个 vector 和 两个 float *, 都长 100000/ e3 F( b3 o( ^8 |; X" ?; X
外循环 6000,里面先做随 ...
1 Q- G' O% w6 K; d% E. e
这个时间是从哪里开始算的?
1 U4 \, N$ I% L5 G/ \' `" \7 ~我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
2 o+ D* y! e- K7 J按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
/ B5 L  l9 J1 j9 R  L8 Q7 U7 r这个时间是从哪里开始算的?
& U7 W% Q1 ]: m5 f0 P我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
$ Y6 j1 M% j8 ~" G. m) @! ^
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
/ d' @4 G) b# v3 C% `你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
0 F2 O) y7 ?+ G) V& Y2 h. h与此对应用数组(指针)花了2S
1 W# p; B$ v" C% m你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:542 `5 N5 i3 ~" O7 S8 H. \
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)# w7 ^; u8 j' Q$ Z3 P
{
8 X6 S, V! o* h6 l7 j! f        comp temp, xtimesy;
6 |5 \3 a% n8 ^* D: v
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
  r( a) P/ p% L% j
) l; ?3 o2 C- q8 g6 k
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
1 x! z- Q9 ^, z& T我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% @1 |" Q; H* ^- r8 K4 x6 B5 l! o. w6 V
...
; W+ |, @& W- F) D
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
0 \- Z0 E( [6 K. X/ F; E/ s& n& ?; w/ H6 h- l" p/ |
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ; H& r) u" D* R
0 s! O. ^8 z) d$ a$ L) @
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
1 i7 N3 L* l& I) K4 F  ]有空时我会试试 SIMD和并行,看看能提高多少。
2 x1 b1 j& b- g% r( m+ }过去7、8 年没有正经用C++ 写过东西,没有 sense 了 / a1 j' S5 h/ l: v
谢谢大家的讨论,I learded a lot.  红包已发  5 x; L7 n: D2 C4 C8 W

9 k! n. o# I& R
6 D0 P, y9 k6 t) A9 g9 H
3 P2 l/ \- K) s" s3 x* Q& H' p6 I, _: u0 q





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