爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
5 o1 ]8 D$ j0 m- h
( y' @) b2 [0 D1 w& T# o* n( t自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。7 x7 F+ ~( y. [1 d5 \! C

+ y5 k. U. h1 g速度优化问题真的很有意思啊。
# l9 b$ Z0 F2 i- w% P1 h* z4 C/ h- Y+ g2 a' D# i4 H
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?) h- D5 ~' a$ Z7 s( `5 p: W
把代码贴上来看看?; Z' ]+ I( S) j: V

) Z/ F0 r# c3 @; D1 X难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 / Z/ R+ R9 m% j" s2 K/ f/ A: w
数值分析 发表于 2022-9-24 23:04
, [( J% X  l& e7 p拉下来?拉多少?0 u; O- g  j- x6 e. }
把代码贴上来看看?

! \2 |. Z  u; o5 q% c% @& s  o
0 c/ M& Z7 u( }2 _$ svoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ g% n* g/ }% @: `. Y; p  t, }7 |* n{
) U  T& ?8 P3 F: I+ F0 `        comp temp, xtimesy;. n6 e0 [; E* ]4 L. x
        xtimesy.re = 0;/ s3 i9 R$ j; v! H
        xtimesy.im = 0;, Y2 L" n  i2 G- P) V1 G' z1 W) y
        int j0 = lenB - 1;
& I' d* k# e( q* M: I+ [        int    i, j, i1, reali;4 x& W. p) J' Q; h3 I, ?9 e$ p5 }8 a
        if (lenA % 2 == 1)! S( ]2 i% {. }% _, ^5 Q
                reali = lenA + 1;
, O; t4 k" e  H8 m( j. M5 J        else
: k$ V0 ^" S- M                reali = lenA;
! M, [% b" e0 ?        reali /= 2;
' @. p: z! z, [7 v- D( y4 f3 G6 B. b: M# r2 _) D" O" i, V
        int nconv = reali + lenB;
! e. e- _1 _. B% q        //#pragma omp parallel for
* B" p- g8 P8 P4 r6 d        for (i = reali; i < nconv; i++). f" @8 a3 K8 X: E& a" ?
        {
/ u, S: |6 ^9 v( E# u+ S2 G3 \# W                temp.re = 0;6 Y! p& U0 Y( V, h
                temp.im = 0;
( a& `# l1 q" x" b% _/ A) P' E                i1 = i;+ Y5 \5 k7 z: i# q( l$ f
                for (j = j0; j >= 0; j--)( e3 g! _! q& J" ]$ M. f, u$ Y
                {- w# ^# z6 Q) Z- p9 I. f" c  k
                        /* floating date operation */
# O: ~6 D- ?% o6 }- K                }
$ N5 @7 f( R! U3 Z$ @7 ]/ C
        }
1 s* U+ @, s& L6 n) Y5 r4 _}% ]+ n3 W3 ^1 Z8 `8 ^% @

( x$ ^, R* L( a. Z* t. d9 D! D4 A9 nxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
3 n5 V: F& d) h+ N% s, `) F- M! H8 a
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。0 r7 P+ h+ W; k9 o7 h$ a0 b/ p; x6 {
现在call xcorr 100次,耗时78s.
9 k  f2 _/ w; D4 z+ h# D. ?$ M
0 S9 b0 W( ^4 Q9 L% Q如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
2 w7 ]' Y" x% E6 d) `  s, R3 q
5 D+ j8 J  I& Q  [; ?- h
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
; i4 d, M# D: [' U& dMaybe Debug mode?
6 b) Z  |$ V3 G9 ]
; ~! D4 M, T5 _1 G' T7 p
不应该,看我上面的回复。6 P& `' p9 I  E  p! N7 ]9 E

. K. _' r- E8 q6 @我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 2 T. f# B) t; u7 }2 b
雷达 发表于 2022-9-24 23:54* v8 D7 e1 E5 D
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)3 n8 B/ o  z9 n# l& t
{6 b+ _, v. ^" I
        comp temp, xtimesy;
' P  s# P, i9 C
6 j5 a, \( I1 S; h  g
这个不是这么比的吧。。。
7 O( Z5 P9 M, y2 B
% I7 y. H) r) d: K2 J  G5 g4 Q0 ^您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
, Z0 i" _* A) C8 V4 h/ \: I2 b+ D0 v8 F0 `1 O0 N/ g
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
% h3 W4 |1 f; h2 V$ g9 r' z
数值分析 发表于 2022-9-25 00:20! |5 J( t$ q( }% o; n
这个不是这么比的吧。。。
1 c8 i) S9 }  j' |$ ^: V( r. ?% ?) ^$ G4 t
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' K8 p, Q% X& P$ p

! j# D3 K" f  j" H" ~5 Y有道理。
' @* l0 h( |$ @- U) g  n所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。$ }1 n; V) S3 D: G( i* l5 a9 z

, h2 _: o0 P" z( S0 S- p我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
4 g: m6 |0 J6 k8 k: ~有道理。" t- G- e' ?( o
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

4 `  l5 M6 ^: D- Y1 y9 ~5 A" M! I你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多' N$ K; z# V+ v
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:209 ~  I" l4 m& A3 @
这个不是这么比的吧。。。) g9 _& z, ^; e* f$ y
( p& H& Y- [4 |+ n: c
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

9 \% K# N  O4 k# g* W7 Q3 t
8 h* I% [3 c% {8 V7 _现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
( f3 c) }% I. ?6 ]6 Y2 r
沉宝 发表于 2022-9-25 01:481 d0 j( P0 e$ t! [4 P
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
+ b, s( q, x* |: T- p
' \0 W! ^! J, b; z/ F4 R" Z1 P
是的,兄台说的对。! r; q4 P% e& \' M) d4 N# I
3 A$ t  M; G4 @: ~2 @9 k
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。$ Y9 J. `. f9 Q" c

, Y, X! ]' L; x1 x; m3 z, a: _) t雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
: e% \+ q$ ]3 U7 U% d" ?2 Q, ~0 e+ C, t/ ]7 `
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
7 g' Q' A/ Z7 L1 G  [2 S1 {1 y! L0 `
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 / X, c) |: t( h( ~/ w# R
沉宝 发表于 2022-9-25 01:27" w/ f, t3 l6 u3 s' i7 ~1 N2 F
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

) T5 p6 o0 u, `4 ]2 X3 t% H
* ?5 M0 b. E1 S: w) b- z又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
2 }& o0 i5 c  K3 Z
: H# ?: `1 m, H' D! ^我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:473 g" k  X9 o6 b# o! w! ^
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

3 P" n. I% @2 s. s时间差一倍的结果可以接受。  Z: {! ~, I* L3 W0 c! i- m4 R
# c" Z; ^: ^4 M& A/ v
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
; O! M' C( F) {' k7 E( G# g' ^
雷达 发表于 2022-9-25 04:47# J" T4 D+ m. |1 o  L6 x
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
8 l5 M! _- f) t2 {! V+ o. _, g. }
( ?: H$ M) y$ [8 D! y
1 f; Y1 L" V- w# f" q5 {7 V% r) p

4 u  J3 u9 O; U0 a5 r7 d! c能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 V2 \3 ^0 V" [% ~! L
数值分析 发表于 2022-9-25 14:588 H1 z: ]* `7 U8 B
能不能把这个也贴上来,看看和上一个有什么不同?
! o+ ~; ]% B5 t
理了理思路,重新做了一个测试。; _6 D; f+ Z( Z
做了两个 vector 和 两个 float *, 都长 100000' s( [, c8 E* s" k
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! P6 X5 k6 {: H* t4 S& y  f9 M! f* m. Q$ Z$ ~2 i
内循环试了4种方法,
% @5 S0 ?+ j" D( v' d3 o1. 直接调用 vector inner_product 247s & v) X0 F2 N, L
2. vector 循环点乘累加 237s2 ~; L7 y. w" S% L4 L3 ~( g
3. float * 循环点乘累加 204s+ K7 P  O  n2 v- v
4. 空循环 100000 次 202s! I2 ]2 ]+ x4 ?& t3 k6 k) @5 M! K+ q

$ ]1 B. N7 [0 z不做内循环 200s' y4 L: c+ [5 V2 h0 Z2 y

# u& \+ u( c1 k, g你昨天说的对,内循环本身占比是很小的,大头在其他处理。1 E9 q* A" \) M4 q9 u
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。: w/ O# [" X7 y4 h2 v
1 X$ E' X6 l7 D. e
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
4 Y8 b7 Q. h# W' z$ {+ D$ v' e: q+ m/ \  E$ a
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)5 E& A% Q& c  ]) v9 ]  }- ~
: H! {/ T! D4 `% e
        std::vector < float > vec1(N);/ a$ b+ V& k& F5 D8 b
        std::vector < float > vec2(N);
6 H, o% f3 |0 c  I( J        float* b1 = new float[N];# Z' E% Q: M0 j. F# }9 C
        float* b2 = new float[N];
& y" E7 x# N" f3 ?2 b7 H. y/ c5 p8 {+ L& R
        for (int j = 0; j < 6000; j++)
* n$ ?1 U( Q0 E0 y2 p- Z$ N        {3 g- k) a! n1 r7 H; H5 \
                std::generate(vec1.begin(), vec1.end(), []() {
; B8 Q' B; E1 p' u2 \1 h6 v" L8 J                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
. r* u, W0 ?, _. x# ^                        });, t( _( q/ {$ h, i
* X( s$ L0 [9 f, O& x& y
                std::generate(vec2.begin(), vec2.end(), []() {
; A# q' p6 ]4 A7 m; h8 o+ }                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
% K7 N$ E: u  Y) P                        });: N$ o# L8 K( G3 q1 C2 n# @
" i) U7 P! [* F( Y# n! ^' T
                for (size_t jj = 0; jj < vec1.size(); jj++)
- |8 |4 m8 n, K                {0 U9 o2 }* H. M
                        b1[jj] = vec1[jj];. w! G0 C1 _. L+ G4 }3 c
                }* I) s3 ~# N8 S( J$ F

) q/ w$ r4 r- r0 x                for (size_t jj = 0; jj < vec2.size(); jj++)
6 K7 x2 o- q% Y3 R/ _9 ?, G: c3 p                {  T5 _8 K( h& m: {
                        b2[jj] = vec2[jj];
7 J1 d7 O; F, I" X7 ]2 p                }7 n" b; S5 `* U8 g. T
9 g9 n6 d7 s& \% i6 p! v7 y
                //Method - 1  N=100000 247s  
$ d( r: G- f9 ~( b                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
, W- y9 J) a: L3 @0 B                                
+ S8 ^& }, y+ N                //Method - 2  N=100000  237s
! A9 ^+ W8 b( _! p  V: D                /*
. X7 \7 n; R$ p/ A                for (int jj = 0; jj < N ; jj++)- I! H3 L7 p  m1 b! P' d
                {( I. x) Z! u" _  O
                        fresult += vec1[jj] * vec2[jj];7 w9 j5 \2 }& V* w4 F: @
                }. o6 p$ o& Y+ [( p* n% L7 n
                */
" F0 o, D: d" O                                
: L% m9 j8 x- S! V! p                //Method - 3  N=100000 204s
  X* a$ y* ?8 L  C9 h+ F% t                /*3 H  J6 V) d; |" J
                for (int jj = 0; jj < N; jj++); B, A' v! k8 s
                {6 N. q4 z* r, G2 k
                        fresult += b1[jj] * b2[jj];
( Y" e4 G- P% i, b/ H                }0 Q0 \" _7 f/ K
                */: B$ d  G" H6 B5 I- x4 N* G

; r: S3 J/ _& m- ]8 c8 d% U% Y                //Method - 4   202s, X* [8 |; L" T7 s
                /*
. U  J4 r( D3 \/ r* o                for (int jj = 0; jj < N; jj++)
$ s( m) k, a5 @# L+ D                {
6 a9 k; k; ?1 u  L* B3 d4 b                        
2 [) K: F0 ~  C                }* d& |! V& X4 q4 i
                */
( I2 F% Z+ o4 m! `                //comment out all methods, N=100000  202s                # z" p2 z# c; ~  p
        }
% w1 _0 v/ J, d$ b( R1 O: U- k2 p! E) f/ y
        delete []b1;
# O. V4 c/ @2 z$ B( A! E) {( ?        delete []b2;

: [& P, Y3 _4 I3 i1 D8 T0 O
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?" y; E* m% a$ G( L% i0 f, Y

/ O8 r! v4 S, D' J0 k/ g: N+ E3 @你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?: u* M. I# |0 K

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15/ D8 h" U5 |, |% s
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?+ `1 M  Q* y6 @- P- C

6 r: G! V6 t- [+ _9 i3 \  R你第二个试验里面的j在循环里面又重新定义 ...
6 @  s* D; j. E# e& D) N
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL6 C# O1 I1 a- q- _+ r# F* k+ b
+ }1 E( \4 p# J: _6 p# E
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:164 O% M( c& G8 Y; ]1 c  X0 N  }
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
  A# l0 G$ r) G( y+ c; Z
* d& h# Q9 q: @- a4 l" p不和它 ...

) O& o" ?2 R% z! @; n/ y: J6 H; Z8 L- ]1 X* k
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
7 R$ p8 W( v& W+ v5 o2 B后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
9 h' Q- A( A% I0 b+ pvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB), V6 _( G0 z3 z& ]
{
7 }. @, }3 p, Q' B        comp temp, xtimesy;

3 F4 P4 Z# L  T- w1 `; r3 p- A4 L这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。) ^/ U! [3 B- x  q
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
! d/ B- L$ O$ G6 s3 C/ b/ lVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30" ~/ a3 G; @$ E& a3 c. s
理了理思路,重新做了一个测试。6 `2 q0 F$ i7 t' T* _
做了两个 vector 和 两个 float *, 都长 100000* ^$ [) D" ^) d, b
外循环 6000,里面先做随 ...

. P9 `, k% [" v. p7 H+ {, N这个时间是从哪里开始算的?
3 q8 ]+ t9 q* V; x我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
( Q8 F( F( r% z% W9 o# h按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39) O# G# j) k# ]5 ^9 ?
这个时间是从哪里开始算的?
5 A8 t! W' J5 v我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

: |9 A* F7 q) G3 N8 J9 c. @我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。- y6 @* g+ J$ Q0 f$ A( q
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。+ ]1 q1 l. J" _7 T3 ?# k
与此对应用数组(指针)花了2S
" I7 t/ g9 n: T) S' o4 B; d你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
8 O/ f' l8 d+ bvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
& ?5 Y+ J1 L# A! `# H7 `{
3 t# y, X- f8 S# y3 O: ^        comp temp, xtimesy;
( b  d  H6 U4 F/ I
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
" R/ \8 ~  }1 `7 c" ^, l. M" p  w7 i; I, Z# u) ?/ w

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
+ E. Z, L$ o- C2 t我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗0 A8 ^# I9 {3 O7 {# Z
, V1 G/ S. W$ L5 n" U* V9 J
...

9 E! k) O+ K( O, _. k你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。# `9 a3 A" b% E3 H  l7 x  J( w2 y

& J5 ^" g! R* J$ h) e3 n6 }( L/ E雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 5 @- V4 {/ H3 ?
4 F$ ^0 _+ c* T+ g- h4 F
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
' a$ N1 r* J% r& h! m2 D有空时我会试试 SIMD和并行,看看能提高多少。, [& R6 C$ R, N1 y/ g! |
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 % M# i4 g2 X9 K' c
谢谢大家的讨论,I learded a lot.  红包已发  3 r. @- y, K2 n5 r+ I6 V
+ ?/ X) k+ j, ]) \3 ^; v0 Z1 u; e

7 |8 j, f; `6 S% G! S/ s
7 P1 }% c# Y/ z; y( Y
% n% E& r5 D) h  H+ O% w




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