爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
7 X9 v# O( l" D# A7 }% w$ a0 I
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
" K0 i. w8 m$ x( d: q9 }4 T( V
3 M# z1 l" W& J速度优化问题真的很有意思啊。
3 G7 r$ v! U" K# j2 n( V  ~1 n8 E& t& _. w' {) v" u
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
: y( j8 g5 d* X: F把代码贴上来看看?3 ~6 g# z! D9 p: O

) N2 G# i- H' Y& S* W难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 " t* i* ^  L; o+ Z
数值分析 发表于 2022-9-24 23:043 ~$ w1 c4 g+ {$ O0 J
拉下来?拉多少?6 p2 L  R" ?* m! W# o8 t
把代码贴上来看看?

; b+ c) D1 l: |+ I  A( X' v2 j1 c( P' r; k
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)+ ?3 M3 U6 X' x& n. S
{2 h" ^* P. r& E6 D* O
        comp temp, xtimesy;
  n' b' [% f. Y% u4 Z8 V2 K        xtimesy.re = 0;
9 R3 p$ B2 ?. s6 h2 {# P        xtimesy.im = 0;
% k4 H- O6 v/ F        int j0 = lenB - 1;9 D3 N2 R4 \5 s6 l
        int    i, j, i1, reali;
) u" B* y( H; n" Z# K6 t        if (lenA % 2 == 1)
, k: M- }: O& [                reali = lenA + 1;
9 k. I6 M$ p$ r2 w* n        else
! J% \0 `. N( f5 c: R/ A                reali = lenA;
: u( I( A, f5 k        reali /= 2;
5 b. @6 z& d. h$ D2 k. g" S
( m& {& G7 l9 _. m  ?% P        int nconv = reali + lenB;
8 }5 R( P% u- h; a5 V        //#pragma omp parallel for4 P9 d8 j& T# g/ a
        for (i = reali; i < nconv; i++)# b& v# v1 T- _. r& I6 @7 R0 @3 C
        {
" o. _" J: E$ g3 T+ ~# J/ E2 e                temp.re = 0;
1 x8 p% t1 q  l* d! y( H  [2 U                temp.im = 0;$ x" y% T$ x+ i; U
                i1 = i;
5 l/ t/ K- f3 K( z                for (j = j0; j >= 0; j--)9 h+ D  `$ s7 Q& T$ K( O
                {
4 Y5 f) `: _( y. V% b' m                        /* floating date operation */
( V$ b! e  A' e: S( S8 I                }

9 l2 `- u* d. \: {( H        }; R4 b: g5 M, X- n, n( l
}6 h7 f& L* t% f8 R% x

6 \' |8 `2 N6 H5 J0 L. ~( Qxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样9 a& ?2 i1 ]' O! l
3 l1 `. w9 }0 {% ^/ L; u( F
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。- ]: x( V' q0 N$ g/ i( [! i
现在call xcorr 100次,耗时78s.# O- ~4 L2 f) Q0 G6 {) w

* @5 i* c& E/ e) t3 p' H如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 1 Z% ~+ q5 z- Z- i* z
% m% G  u! G5 f( H, x

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
  ?4 J1 Z" l  }' H( h- hMaybe Debug mode?

8 \: W8 {9 T1 g  t9 l) h
4 m1 `0 g- ^) `' v不应该,看我上面的回复。
% G) d2 E6 Q5 \% C
. l7 ?3 s. z( L& t( D5 t) o我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 7 q* \( D6 x0 X7 \8 Q* `! }
雷达 发表于 2022-9-24 23:540 C9 x3 G. K7 M$ H3 i
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB): W  o: \4 U9 q4 L( c! m
{2 g3 v4 ?( g7 L# t; Z" L! w5 e, c
        comp temp, xtimesy;

( t8 l( K9 g) Y+ [8 ]- I6 Z! R. Y
" d5 g. _2 T% y' Q: q6 v8 d这个不是这么比的吧。。。
' i0 f% Q/ j2 u# |
7 w! \) r  Z' @您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。3 v- ~- E5 d2 S- `+ L9 r0 m

6 N5 n+ I2 f# {$ b" L1 y而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 7 |4 B% E& ?9 Y
数值分析 发表于 2022-9-25 00:20
# ]* H1 j- m0 @- g8 Q5 h这个不是这么比的吧。。。6 f" v, u6 o* U. K& r8 ~# Z
$ b1 g& V$ {8 d5 Y/ n
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
- `1 x4 L; k4 K0 ^6 Y4 Z4 I! S

; {, z/ _5 ~+ U9 C3 z* t$ E有道理。
4 @9 h) k- Y+ B. K所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。2 n3 A: n- Y3 O9 K' j

9 e* W' v( u* ]. I我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
* ?% G: }9 W  S有道理。3 _) `+ y& d$ e7 f
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
( z0 S# F0 m$ V
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多3 y5 j8 G. e& m
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
' _' B# w: l! p: K这个不是这么比的吧。。。
$ U% z/ x$ s1 m% A; K: c. p
; h3 g: ~4 Z% R$ [! `- D您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

" S5 h' q2 c6 L, n
. G8 M" @, h8 c" B现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
4 q2 P. N$ J, R$ G
沉宝 发表于 2022-9-25 01:48
+ L% r" J9 b* B* N, R: ?现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
5 Q& o4 }5 F! V/ R( o

, }# P: \9 J3 |, k- ?+ Z5 l是的,兄台说的对。. f4 G9 K4 h5 r; l

; k- W1 T+ q, E1 U3 o" J3 ^0 j) m其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。# M9 o9 n" o  ]3 W! U% }5 ?

1 P! H, ^% L- F6 N9 ?" d" c3 ?# x" [雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
$ k7 y: X$ Z6 L+ i9 w/ W: H
' r5 N. \/ b6 n3 j比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。% J  ?9 n6 W6 R5 n" p

/ H; |# ]7 Z8 s# C当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 " f2 Q3 B- h6 d( c( _
沉宝 发表于 2022-9-25 01:275 M  Q4 g. r' O
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

5 y" Y$ P6 i: h- l7 y
% s( Y) X+ [8 W& |又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。; f0 ]! m& j, v' ?
( L. e% l# p" ~# u, J0 Y
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47& f, E7 ~! \, I5 L* ^/ t
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 ]# J, P4 h& f
时间差一倍的结果可以接受。
4 v3 r+ R1 u5 T! B! ~# ?% r9 H0 a( W' f4 o: F
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 6 E- l6 D! q, A) |4 z
雷达 发表于 2022-9-25 04:47, B0 l3 v# e9 |" U
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
8 Q5 e' E2 s% K# a

/ B. N* M( `# G/ ]. C/ h- B) i
, M% ~+ M  w4 X. I, A& Y
4 k& N0 q+ p" w% f$ n. }能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 X$ ~+ U( \- A# i' K# V9 ?2 W# C
数值分析 发表于 2022-9-25 14:588 I" z2 O' }4 |: S) e3 F
能不能把这个也贴上来,看看和上一个有什么不同?

$ l. l! X# z! c% }理了理思路,重新做了一个测试。! h; {- L# V  c- u8 B
做了两个 vector 和 两个 float *, 都长 100000/ P$ h0 Q( Q( M& {4 C+ r( Q1 G
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache., ]& o- |- r$ s+ w- X

+ N# P. Q8 d# h2 _内循环试了4种方法,
2 m( u$ a2 c- x2 k" c1. 直接调用 vector inner_product 247s
! S* X* o4 ^! u/ }- R4 v$ t2. vector 循环点乘累加 237s, r5 _0 U( C, s' l. N
3. float * 循环点乘累加 204s
. _' ^( d( U* Q" [4. 空循环 100000 次 202s0 m& h( j0 l" ]1 y( N( f+ l

  ^, c1 A% M: d- a不做内循环 200s% A- o* j: H$ q( l

# v% c# ], ~2 _- W你昨天说的对,内循环本身占比是很小的,大头在其他处理。9 s( \& Z7 Q( `& n
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
5 l8 y6 z" |, X. g
2 _1 N& X! }' M6 \至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
% G4 d2 G1 x  [/ L; A
. U7 s8 ~: J, O, A6 u- X# _(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
2 w1 A; X& ?7 V" e! R4 t# p* p# B3 l" C# w$ [& k' @
        std::vector < float > vec1(N);9 A2 R/ J; E) n& ]3 k9 r  ?
        std::vector < float > vec2(N);: Y1 \( r/ e0 V; Y0 J+ H% n
        float* b1 = new float[N];
+ C, ^6 p2 i- u" b4 i        float* b2 = new float[N];
; z! r! R* A% s. m9 I; G! ]: b7 j; Y3 r- Z  C  o
        for (int j = 0; j < 6000; j++)5 W- ^  F( G* i- o' G9 g8 R
        {
" I' T# P& `' E  u                std::generate(vec1.begin(), vec1.end(), []() {+ H: b6 n1 ?8 N  X' q$ `; X
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
2 y5 e0 h2 |8 V+ n# s. y* l6 `                        });
' s7 q% n  h, x, X% e8 }) t6 j# w0 D3 U8 v% s  ^5 A5 X
                std::generate(vec2.begin(), vec2.end(), []() {
5 |. k0 ]2 G7 o                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
8 b9 L7 R" D/ f% e/ B7 k                        });/ C2 O4 [: c/ E, Y! g% A- M
& Z! F4 b3 q! s% b4 I0 _4 A
                for (size_t jj = 0; jj < vec1.size(); jj++)4 D$ U7 ~/ G( a( H- {. n
                {5 z; G/ A# x) L1 \
                        b1[jj] = vec1[jj];- {& O7 `# u- G0 M2 w* D
                }
* i' O+ C! w8 Q6 |2 Q! h
3 X) u" l" T  i4 q& Y8 I0 e' z                for (size_t jj = 0; jj < vec2.size(); jj++)
3 @. {" k$ c& L4 _9 {) l& J                {
' t3 z+ V9 Q/ `                        b2[jj] = vec2[jj];
0 o3 ^! {$ c7 B6 K9 a% T                }( E- }* F. \* D" Z, d! [$ O

3 i" `  b) n5 B1 i                //Method - 1  N=100000 247s  " |8 Z: J, C) }# d! S
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);+ `- a7 B  J3 ?! m' L! R  G
                                
# J3 G( N' A+ C: Z! h                //Method - 2  N=100000  237s
/ u9 M2 N* ?9 o) o, d: y                /*# l  b4 c% [! O6 W7 ~$ n8 H
                for (int jj = 0; jj < N ; jj++)
6 C, B  x# K" {) Y) S                {9 [& c, N6 m: w8 y# I
                        fresult += vec1[jj] * vec2[jj];0 X. O+ e$ d' o3 o! ?
                }! D7 C1 h2 k6 }. l1 o
                */. l/ X9 J. a5 X" S
                                
9 B6 e  W" {# Z) ~                //Method - 3  N=100000 204s
! I4 K% @) W* i- S' D# R% d/ @                /*6 m+ F) l+ ^0 [" ^- I. _% ~
                for (int jj = 0; jj < N; jj++)
" N: k( |. L& e6 b" L: y5 z                {  h6 S0 j9 w3 a1 _# t  K2 I7 |
                        fresult += b1[jj] * b2[jj];
* e" n; F6 Z& \0 A                }
+ o5 D7 G8 B! a, a3 c9 Z/ a                */  @( F8 B. Q. m; T; g
  Q' T* _! \2 r) a8 B$ ]; c) Q( {9 ?
                //Method - 4   202s9 d" Q# K, ~. N7 k/ h
                /*6 p1 w* f' g# o/ x" C; c1 U
                for (int jj = 0; jj < N; jj++)
' H. w3 k$ d4 ]1 _8 r9 H; ]                {) t! r7 |! V: g1 _3 J
                          W; V  {3 g+ f2 f9 {- A9 c% K
                }: e. S$ p( O( O8 c1 s) H
                */
* W% l& K  }/ U6 D2 T* E0 r# T( d- r# q                //comment out all methods, N=100000  202s               
9 G& W8 P7 u% f- P: j. v, g9 T        }! ~/ T) w4 s, z% F8 A4 b8 X# M- P

' E9 }4 ]1 v! z7 H3 y( E        delete []b1;
8 ]" k; E; h; F' Y8 r0 P* f$ I- r        delete []b2;
: Z$ B- o/ I% C

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?- U; c% t5 l( I4 V* y, q5 S, ?

% H$ {0 \9 g7 r& T4 C+ M" `你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
7 t+ G) u1 w* @  g9 x6 L
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
" j2 b) O5 r# }- t, M! b. D+ g+ n瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?% W5 j  m8 J, t) r

3 c) ]# q$ u- R; `8 a2 @- c你第二个试验里面的j在循环里面又重新定义 ...

4 |6 t- @- Y- a) w! P% q7 s( Y$ U内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
/ |2 x# D  i3 i5 B$ A/ Q! u; ~1 C
! z: s+ A! m' L不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:163 N9 `5 G  N* P# R) ], S* q: n
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL2 m( j  g* t3 f. v
9 n( m8 D% e% S- ~2 V7 C3 ^; o$ m9 j
不和它 ...
, W2 }. S8 W  j2 p" {7 x* u
+ l" Y( X7 W3 J/ P+ H
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。  P, \7 q& @$ \$ J
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54- H$ D: Q) m. M' j* D& G
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)7 ^+ l* V) q3 _4 x  C  g) w
{( j* n7 s6 u* E) c5 ?
        comp temp, xtimesy;
( O( @1 ?. M6 p- E
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。/ Q: d- x6 y* O, {/ K0 P
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
; P3 b4 Z2 G) eVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
, T/ F1 J9 ~) k$ X  }理了理思路,重新做了一个测试。
& \( y8 K) _- T7 ^1 E0 o做了两个 vector 和 两个 float *, 都长 100000
8 A  b' ]/ x3 N8 s) }外循环 6000,里面先做随 ...

, x# Z3 v5 D7 D- E6 E2 F这个时间是从哪里开始算的?: X$ f; m6 ?0 R8 e% H  o
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
  e1 o5 ~# H8 `% E, F0 u  S4 y按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
/ T% e% w# x2 V2 K1 x这个时间是从哪里开始算的?
1 w* A5 e5 `7 \" ?6 J我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
: L* x7 b( B7 e$ H1 J
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
7 b' L. ]3 _; M/ x3 e你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。" e% o1 b* t9 q& A
与此对应用数组(指针)花了2S
% s1 @/ B2 ]; g5 ~% o; Y你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
" E5 M1 e; m. a1 b& {* f: [void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)* `1 m0 a/ w5 ?  @
{/ u7 X+ P; X4 |8 V, f
        comp temp, xtimesy;

- [2 ^  z" C# y2 w0 p" L$ H我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
6 L7 g& y. k  L% k' w3 p% I+ k7 Y; ?5 D

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29- W0 y6 a' }( y
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗: x; `6 h6 a" E% b* Z
3 n8 R5 Y; T$ B$ A" ?8 Y! _" H
...
& e, k0 Y: k- B6 G- {  D, O3 s: w
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。5 P3 m) F( @& D2 D: \
. N  R5 t, V, B# T  ^6 _
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 7 M# l3 ~# w' U3 ^

# O! `6 `/ U3 h4 M是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
4 o8 O* ^& s  ~6 c4 W" j! A有空时我会试试 SIMD和并行,看看能提高多少。
5 `) P& v, x- F& T过去7、8 年没有正经用C++ 写过东西,没有 sense 了 % Y* P/ z, [7 s+ b
谢谢大家的讨论,I learded a lot.  红包已发  0 B! {) a8 V/ V0 E0 s' R) T' I; V

; P8 Z) F: ]1 E) M2 E' ^' p
2 W  o5 O4 v; a- k( Z6 b! G! n8 |0 h3 X  A: T# T
/ T6 F1 G( B. |3 G# u





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