爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
* t' a3 y; V0 r7 `8 Y
1 O5 @) V1 C6 P# r8 c5 u6 H自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。* H. i; R8 E, c+ R; ~' R3 _
7 @4 K2 ~6 Q8 r& ?1 s, `
速度优化问题真的很有意思啊。
& j3 [1 S1 s% [0 \* ]2 i4 @9 N5 V6 a3 Z7 f
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?$ n3 ]/ c4 q1 H& U' n6 k
把代码贴上来看看?. ~9 W+ ]+ D( O! L( [

6 k4 |5 n, p$ Z难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
8 Q/ U! i9 [4 t+ j
数值分析 发表于 2022-9-24 23:04
* a5 p2 k& z4 @% c6 \$ g" Q# h拉下来?拉多少?7 M8 ^8 k6 H! w% Y& a
把代码贴上来看看?
3 e! w0 [  R$ O7 f
0 o- v% d- C! k; D% u
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 Q% T2 k0 K# v# r
{% [. A& I6 N9 Y# Z' f2 J
        comp temp, xtimesy;( G' B9 ?3 f/ W% q. S: M1 h4 S8 ]& N
        xtimesy.re = 0;9 Z4 }1 T: ^# C4 [) E3 x. K! p. o
        xtimesy.im = 0;6 C* Y) {- Q5 ~* m( z: m
        int j0 = lenB - 1;* Z8 k! C. \# n/ p" F$ Q
        int    i, j, i1, reali;
4 s5 O4 P- R, J5 M$ K: b% t        if (lenA % 2 == 1)
. J( ?3 A6 x+ X                reali = lenA + 1;5 T4 B' U0 }  }# F1 j6 n
        else
- i' O0 ]% G0 S. I" p                reali = lenA;9 d5 S1 C+ O" J" U4 a# d
        reali /= 2;/ N! `+ w* n3 ?$ h1 H5 F

1 b& J; Y" v6 E, U: g        int nconv = reali + lenB;. z3 e# l! H( y0 j$ v1 D
        //#pragma omp parallel for! T& V& C3 j# L) A9 |" a  }: i; I
        for (i = reali; i < nconv; i++)' B, g$ O9 |( w) v. h
        {. R7 s) }" U9 s4 h7 l4 a: i* n
                temp.re = 0;) C' u" V5 O. E1 w& N2 i: W
                temp.im = 0;: R( b  L- }; p- E
                i1 = i;+ i7 U1 R# a# ~3 S, T0 P5 `
                for (j = j0; j >= 0; j--)
9 V4 h/ X; Z# ?3 }                {: u; D1 n2 p% ^/ s
                        /* floating date operation */
$ \# U7 h1 U! X% C3 U; T) g2 U                }

8 E( ^6 B8 y- B4 D" Y# K/ Z        }# K2 M9 v) h+ c* ~4 O8 Q5 f
}
3 P* b: c7 w+ O+ [! O: _7 c' Q4 I8 k" O1 m5 b1 Z4 N
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
8 s- Q; T3 L7 ~# P5 a- X" v: t" N4 k! W0 M! L
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。6 G: f, S# C' S" x- Y. a% N
现在call xcorr 100次,耗时78s.
$ u' Q4 p& B9 _
5 g! W  x6 d, }" ~$ f$ J7 f. V5 s* {. h如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
/ u( a: v! _8 c' {5 x' f3 F/ m# i0 A  k2 r: o+ n2 U" C

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
# f, F9 ]% V( x2 e$ ~/ SMaybe Debug mode?
# u8 D2 H, l# R/ V2 p& S

8 D: Z3 }$ Y& g8 ~. L不应该,看我上面的回复。
, J( T2 O$ _" Y* r' s, \
# y! Z2 p' q) N! \5 v/ n我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
+ Z% }; Q& i. P2 ~- E/ E! E
雷达 发表于 2022-9-24 23:543 F' B! q/ P0 x5 M" K. c6 X5 _
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)4 r8 D5 _- z% I  q) f; j# |
{- X- _2 L- m/ @4 _# m
        comp temp, xtimesy;

6 F! e) ]7 c8 u9 R
* j  @9 v- M# W2 ^' @+ `这个不是这么比的吧。。。
" u5 S) J* c1 j0 S9 m
; H  V6 k4 N( x2 b' E您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。* g  t3 l- J' {

/ y. V, E9 B/ l. ^: Y而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
3 r8 N! t, T$ c3 m' D7 F. z' R! q  a
数值分析 发表于 2022-9-25 00:206 }$ k9 Y4 F+ E6 \+ u- U
这个不是这么比的吧。。。
  r/ k1 m" K$ P- E4 O
1 ^  F6 j# w: ]) o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

9 @9 ?: ]3 Z; K* z2 _1 p0 c
+ N6 _9 {9 y# |, h有道理。
2 D+ A4 m- a8 j5 k2 _所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。- _1 E4 @# G8 Q' q
( ~* w. D/ o7 S
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46/ i; ^- }4 h" J( W
有道理。
0 _0 A& h6 e8 z& U所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

4 p0 l/ E) S5 i  f3 }" ]你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
6 G4 {& i6 y# Z5 b$ T% f( R: z( y# }Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20, ?  d$ b9 b2 d9 g- S
这个不是这么比的吧。。。
" ?8 }; `; j+ r0 o( o: N7 ]1 p
. B/ Q% G6 M; o' a) s您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

. t  Q  O9 ~; M  s" U$ `
4 u& B3 Q* [$ e% |$ |, z现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
: S. q5 a' J5 T; }2 n( [
沉宝 发表于 2022-9-25 01:486 L8 b, f# q) T# P3 x) o
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
& n! l- p- u& K/ _

# i+ D& i) e4 E5 j4 q是的,兄台说的对。7 R! }# e# @5 ^9 \- W
4 g  t$ v6 a/ w
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
6 E  Q2 c" |, p2 a$ j2 @# n  I/ J: C1 j
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。: c; P# x3 v0 H1 `* p

) ]1 M7 d8 u0 Q比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。' r# P7 K; ?7 R8 l, \: @
0 q& p  h( b7 r$ o3 F' Z
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
8 ~9 m: Q. p: a9 p* A
沉宝 发表于 2022-9-25 01:27
0 j& k7 r% o6 h2 m2 a你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
7 S# {( F) o; F
( Z9 d0 a! ?/ F4 J9 W
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
7 ]1 h5 @* F/ E* C: F* D6 G) |
8 \0 E, P+ g9 w2 L& F) ^我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
, @5 x' \5 p; J) S9 @" R又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
& t3 \2 a6 J0 A' J6 W
时间差一倍的结果可以接受。
+ J/ Y  e4 B: y) ]% e/ I) N2 X2 _! f# `) i
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
2 Y! l2 q# G7 ~3 m
雷达 发表于 2022-9-25 04:47: @* y) p$ ?% \# q
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
" d( f2 j: D# ]+ o9 t( \

0 Z# V0 W; T& ]3 G- l& P  F( q. o  D# q( f8 a) U
) S9 s7 A" t2 i4 c0 h
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
4 g7 S3 V! D- `9 |/ j
数值分析 发表于 2022-9-25 14:58
" L0 Q. I/ I; @3 u' B能不能把这个也贴上来,看看和上一个有什么不同?

0 F) G$ y. x2 U. p& l& U; R理了理思路,重新做了一个测试。
. D  ^$ I( _1 l0 n3 U做了两个 vector 和 两个 float *, 都长 100000
5 E# C& L% J5 G外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.) {, M0 m- r2 }# C  J

4 S* u9 m+ a& K2 z( d内循环试了4种方法,4 I- |* I; o5 i: d
1. 直接调用 vector inner_product 247s
8 C1 N, k% J: c7 V' }* ~2. vector 循环点乘累加 237s5 w3 x4 S! F/ _: n- c) U
3. float * 循环点乘累加 204s2 g* P2 ], }& v- r# X
4. 空循环 100000 次 202s
1 ^! p+ z8 U/ j' \
; g0 m7 J0 \5 ^& G6 }2 y% s6 y不做内循环 200s* c0 m8 }" {' F

9 k7 k5 `5 y, ^" C, \你昨天说的对,内循环本身占比是很小的,大头在其他处理。) s( s. ~& Z* V2 n! s" ~* Y/ @6 x4 u
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
3 i7 r9 V: ]  y* G6 P7 a! y! K& F
  W9 ]( a& v8 I至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)& D0 G2 \' E/ ~- P3 s$ F/ M  P( ~1 f

9 ^6 y: y/ P/ U1 @(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
) q( X* v3 J8 G+ U  Y( H' m
* V( S* a, r" ^: _
        std::vector < float > vec1(N);
4 Z, g6 O0 @( y! v$ `; C0 U        std::vector < float > vec2(N);
& |. f- H- I' K9 j* Y$ S, _$ A        float* b1 = new float[N];2 B1 ^4 ^; M7 l; m# o( B9 y
        float* b2 = new float[N];
( C, ~+ _) n6 L: t
+ D: L4 A8 R! ?- ^        for (int j = 0; j < 6000; j++)
) D, Z& J9 F0 S        {+ G. Z# A& Z" I* z- D: W
                std::generate(vec1.begin(), vec1.end(), []() {1 v7 D; F, A( L/ o( r  B3 |
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
% T, ?, j" P, T* Y  S                        });5 [$ [1 W1 l0 f! ~. O
$ a7 L  E4 U7 G) H6 i
                std::generate(vec2.begin(), vec2.end(), []() {2 D! s! q8 @" O0 @
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
: y3 y, }( C4 V, p; v: R1 M# Z                        });
: v. J& P2 n% j2 v, M6 \* T
* F, B8 @# @# f: N% E                for (size_t jj = 0; jj < vec1.size(); jj++)
* Q8 l7 S% ]" W                {4 j+ S; a' c* |+ v* a, P9 k
                        b1[jj] = vec1[jj];
9 Z- W4 [# L: l  z. O2 l                }7 a. O- N# r' K% s; B" b

8 ^4 x4 G1 G" k1 e' h4 G1 ~  b                for (size_t jj = 0; jj < vec2.size(); jj++)
2 ]( B$ ?9 o; A0 ^6 c0 z9 p                {1 z5 `/ F/ S4 y
                        b2[jj] = vec2[jj];* W7 b9 Q1 x# ?  m
                }2 @9 Y0 i0 A5 v( J6 W& l
( K- J- g5 X" H$ C1 A3 E) N
                //Method - 1  N=100000 247s  ; k3 Q' J' _. T6 N
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
: _. k5 Y" K2 T  x                                
. ]& V' c9 y& ~5 I3 ^4 Q                //Method - 2  N=100000  237s% N. j& H0 S3 A
                /*
, V: @' [' e$ P, W, z0 ^7 ^                for (int jj = 0; jj < N ; jj++). t; I7 ~* g" J6 K( m( L7 q
                {
0 X5 I5 @# q4 v                        fresult += vec1[jj] * vec2[jj];6 |2 d- u* L0 e( S
                }
$ J3 m- q% m+ Q( I                */- L, }$ r2 O) @
                                ! u( V0 P7 l2 K" S" a. f6 G1 a
                //Method - 3  N=100000 204s
6 J# P" v$ j1 h                /*: |: Z8 l0 b- {) N( u
                for (int jj = 0; jj < N; jj++)4 y" \/ A! h& G
                {
3 L, ?& q! {0 R' l4 d                        fresult += b1[jj] * b2[jj];8 ~  Q1 m6 j1 j7 A
                }3 u) s& K& d  n8 b
                */
  N$ a" F3 Z7 T. H/ S% \
, u% {! n% j5 ]* f                //Method - 4   202s/ K2 I! g4 L* C9 y& T' ?1 T) t/ q0 B
                /*
' X# f( x9 k" }1 J                for (int jj = 0; jj < N; jj++)/ n: p$ N  p4 T
                {% P* c( c# n/ P
                        $ ]& z8 f- G$ ?  S% |; [
                }* Q$ ?, {: z% e- @( M1 d
                */: J/ w' Z# o- l% T2 g
                //comment out all methods, N=100000  202s                2 B% z; _2 f4 n- u# I' L
        }3 S% p  ]6 b; Q' }  C# \

1 |+ t3 ^- ~+ }' L        delete []b1;' j3 ^6 U  S; h' ?# s
        delete []b2;
; T  a/ y: j" i+ q

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
* D1 e& H4 g0 |7 L8 L& H: U- h: u
# Y3 X( f$ w2 {# }* d* D你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
# F4 X3 n3 q) e9 `* y6 x
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
0 `: F. b4 l; @7 }7 V( x瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?) Z& F" Q$ G, t5 W
5 O; {1 k2 ?# M; k7 P, z
你第二个试验里面的j在循环里面又重新定义 ...
3 z  z0 N9 R3 l
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
2 c- K8 y  t7 V: G. f
% U3 `7 q- J6 D4 ]6 O- @不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:169 ?1 [: P( N7 V- S; Z6 j7 z: F' H5 ]
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL4 X" N. K  j# H: s5 A& ]3 E0 j

  w# J3 |1 D  X- N2 b1 l不和它 ...
  Y. b) i5 F; c! J. f4 P+ A

/ m1 A6 p  m* Z不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
+ ^% E, D4 b9 X后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
5 k6 K  j! h; P3 {# ?4 Wvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ c; l2 n4 D. b0 z. t" x  e: d% i
{  y- F6 _$ }/ P6 ~& c
        comp temp, xtimesy;
. t/ e) y; k1 M$ c& w
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。" r$ Y: u1 g& H$ h; f/ ^
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?, o% p6 x5 ?+ ]  q3 }
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
. ~) r1 b  o9 p* s8 z: C理了理思路,重新做了一个测试。
/ X! v  f7 `6 [$ Y, T! v% R做了两个 vector 和 两个 float *, 都长 100000
8 g. F- j' H& E1 q7 U5 E外循环 6000,里面先做随 ...
1 q: N9 ]0 V5 y8 t# h( v, \+ X5 d
这个时间是从哪里开始算的?
. b7 u+ [4 y/ y/ h# Z" K6 [我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
; R7 R5 K9 j( ?' @4 A; f# i+ {* e6 ~按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
( I, h% B3 y5 j" H# z这个时间是从哪里开始算的?" _3 g7 Q5 F* `5 S
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
, f$ A, I6 d: B- O0 Z( \
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。2 C( c+ U' O( w+ _" n. o# O
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
* a9 f/ k, c: R: O0 O/ Q" k与此对应用数组(指针)花了2S# a; G* R* M; O1 r
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54/ ]; e* Y2 q2 l* `- Q1 r1 T
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 I2 \! c/ M2 f2 E: M( Y
{; e9 x* f6 \* r
        comp temp, xtimesy;
' Z# H# c( l3 ^2 ]
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% r) q( l) \  S4 {+ C0 W! U$ Q( }) q* D; Z! j4 B' f8 C2 o) B3 q9 }6 `

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29+ I0 S8 I' P; x
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
0 ?) i0 b/ g5 |" l* o& |! ^- y$ C# D& |, f& R9 U9 o
...
8 y9 t! X" ]$ G2 Y8 W5 d
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。( U$ b" s9 f8 x1 D% Q
1 S8 S* J% q( y
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 7 B) O/ d' T; j' L( \5 S3 x! T8 X
# x" M) E( H! {$ w: u" d
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
8 ?- }' y9 E  ?! ]8 b/ J7 m有空时我会试试 SIMD和并行,看看能提高多少。' k# {, K3 ]; N9 L
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
, _; [6 J# v! g4 w/ U! S# H, a谢谢大家的讨论,I learded a lot.  红包已发  
; P( g1 Y6 @* W( k( v$ T6 g5 i8 U  j7 \  E( n4 w1 R/ s

9 p, `  `1 c+ i- o* B% D, U9 s3 H5 F, m0 L* L. v; Q
) Q" U. t6 L; K9 j" X$ u2 l9 W





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