爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?+ S9 P; W& s7 P6 ?4 I0 ~1 {
. J9 ~- h# t4 r+ W
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
% [# z) K, r  H: R6 k- f  J9 |
) w, Q4 u  |6 l- l速度优化问题真的很有意思啊。9 }: d& W3 w# ^( J

- ]0 j' ]/ T4 ]$ K1 W0 z! c欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
+ N. ]9 [% Z% G% m5 P, I8 x把代码贴上来看看?
) s: l- d8 z6 v* T4 ~0 ]. _; a
& _4 l$ A1 g4 @$ W; V难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 & l$ Y( k: k: N* s; Y( ^
数值分析 发表于 2022-9-24 23:04
' x  p* @( n1 n% P/ ~拉下来?拉多少?. {1 A! V; X3 n( s4 P
把代码贴上来看看?

' Y, w  L& G4 m1 W7 d; e' d+ _8 M+ s! a& m5 n" }8 [: T
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)! j; X- i  t! S
{
: E' Z' s4 Z& J. z4 M/ f* B        comp temp, xtimesy;
% c* ?8 |+ W; w; D/ V        xtimesy.re = 0;* f1 S, ^9 N" Y; f
        xtimesy.im = 0;9 u5 u2 A! K7 v: ~0 f
        int j0 = lenB - 1;
' c! ~- y8 U0 h        int    i, j, i1, reali;7 j. a7 d! T1 w' H6 Z
        if (lenA % 2 == 1)
6 \8 n2 x( D! Y. t4 l1 }                reali = lenA + 1;' c1 \  {# e( I( Q
        else
  u# i( Z, K8 i! _. J0 `  H                reali = lenA;
( Q) R( D! p( e, c0 ]" `* u2 d        reali /= 2;0 ~! Z4 }3 C  E9 @0 t) b6 B

" d4 |+ e3 Z' d: a9 V! O' E        int nconv = reali + lenB;
  |9 w, G7 A: V2 U$ [: w- o, H* s        //#pragma omp parallel for
& {9 P) V6 U7 t- ^7 L        for (i = reali; i < nconv; i++)' X5 _& [$ O7 n8 a
        {
% Z# {$ G. o% B0 `                temp.re = 0;. y5 }, \. Y2 j- y1 m2 u
                temp.im = 0;" d6 ?  o0 v. @* @( L* G
                i1 = i;
  P6 h# b% Y- e; l7 @& C# N! ^                for (j = j0; j >= 0; j--)$ w( W% Z# \! a# J! t
                {
4 v. `" M: N' Q# _, a( n+ e3 L                        /* floating date operation */2 f  e3 E1 J  E
                }

9 |% e: x+ A# {! J% Q        }/ i& H$ y* ]# l( e$ \$ O- s
}0 j5 B: s$ E; @, U
# K. i2 N8 c, X( ^
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样9 W4 \) m& O" N" t+ B! b2 T

# D  x' }! N3 R: ?红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
& f6 G: [3 s% ?! Z- {: R/ g" y现在call xcorr 100次,耗时78s.
& N! e" p; C% K8 ^4 \' e
9 S' M5 t! v& y- |$ ~# P如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ! |- H$ \3 R& {" @/ U% Z
) [! o8 R/ F7 e

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
3 G: e6 O; I* {4 d4 A$ |- qMaybe Debug mode?
, o" N5 W$ ?7 w9 k# K% Z$ j

0 e4 {* \4 |9 d! a不应该,看我上面的回复。
5 E. g( c: ^* [) J
+ A7 `; a7 l8 W0 I& D, h, ^我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
5 _$ `8 E+ Z+ u; l
雷达 发表于 2022-9-24 23:54; L8 f- t: L) m4 F6 R
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)2 P9 n/ U! h( N1 ^/ S" V4 T5 Z0 {9 W
{
8 r9 _8 I% [: B, m        comp temp, xtimesy;
8 ^5 \7 m* I2 p4 t0 B% V$ h

2 ~* {6 X" K: l( j$ \# U7 Y4 L这个不是这么比的吧。。。* N* I5 k- C4 y5 L; l6 q" r

9 R% d) N2 T% F您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。/ e, N6 _: `8 k( H
$ @# l& r2 F7 n' \
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
$ `1 b# v: f* H& z  h4 Q
数值分析 发表于 2022-9-25 00:204 [3 \- T4 Z# ?8 @: L- A
这个不是这么比的吧。。。
0 S8 I) R2 V" D0 N8 d: @8 P; ]) W3 s6 n0 [. \9 I* Z% t1 c
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

+ j0 d2 V6 R8 o; m- i! O/ |
8 p( l7 J3 i. M  Z  _有道理。5 s& @# j; {9 D6 b
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。& h# j$ v* u3 a/ s% d" N. f

& F1 v6 A- t3 W  ~0 }我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
4 L% [- `5 f; ]7 w" W有道理。
, Z9 b% {' y5 Q) S* b, u8 S- i所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
$ A5 z. r% i# i5 D
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
, C3 v( `6 h& D7 C) gWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
' b* ]) l* U4 p这个不是这么比的吧。。。2 w1 s  U( L4 Q

! S5 [- A4 Q: {5 g( Q您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

5 F6 l- v. [0 l
! c! G! R  ~) e/ Y& p/ @% i现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 6 ~: s+ m9 J8 W  v+ L
沉宝 发表于 2022-9-25 01:48/ `1 W+ T2 w3 e) G
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

+ m; T' \; [( q, m% j* S% l( m0 O$ Q( ?) h4 j' j% E
是的,兄台说的对。& f$ ~, l% \& L  m" S+ M

9 E, D. L- a) D3 n8 b3 l! {4 l4 T其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。5 u( ]4 A& M, s7 j
1 l; L2 N) K" h6 U2 Y, S
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。- q, B; C- h; D3 C

' ?/ X. |6 S1 N- n比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
& W' \* T3 B( P- q7 d/ p4 D- P; Z. A% B
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
9 L1 R6 Y  v4 Q8 d
沉宝 发表于 2022-9-25 01:27. |) {/ w5 j7 P6 k4 I8 W
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
0 L; P; j8 r" ?

9 t% K0 f. Q+ `6 `. _又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
: @& v6 v& k; H5 u* [6 I
$ V& l9 @- c3 F$ @. Z+ [; X+ M我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47" [; T8 {8 Z2 A* \3 Y4 H/ _
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

. r& J# e9 M9 t* r时间差一倍的结果可以接受。
% C  ^& }4 M: a6 e  W4 I& ~6 |$ x/ R% [+ R8 R
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 , ]" h% {: {1 ]  l& ~
雷达 发表于 2022-9-25 04:47
7 G7 j( b) ~! D" q( q又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

% F, P, T% j; g7 e
& L9 q2 `& D$ f) ]
0 K- t1 v# }5 v% x1 ]9 r
% _6 Y8 x! a# v能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 * X  a/ z: y1 j* d8 ?$ @7 ]9 P
数值分析 发表于 2022-9-25 14:586 O; c- G. k: _  R$ A0 W
能不能把这个也贴上来,看看和上一个有什么不同?
, e$ A3 v) S2 R4 b! i
理了理思路,重新做了一个测试。* H5 O7 V% R) p2 E
做了两个 vector 和 两个 float *, 都长 100000
  r9 V7 x1 f: l, L( @外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.7 }7 u2 B4 ~* V9 p" W2 w
+ o* c! P* E; u7 n5 f
内循环试了4种方法,
0 g+ F( b/ P( M1. 直接调用 vector inner_product 247s
5 D0 b% u1 T: M! Y# \( B6 t: Q2. vector 循环点乘累加 237s
8 o2 s- q5 t3 e+ N4 V3. float * 循环点乘累加 204s  t6 |7 N  F; f- H( w8 |
4. 空循环 100000 次 202s" H7 b. ^+ g% n
) x% I% z0 |* i( T  X8 ^! X
不做内循环 200s; t7 [7 m; x: g* C& {3 X
4 x3 r6 M) b8 g  s
你昨天说的对,内循环本身占比是很小的,大头在其他处理。; A* c5 `% d) O9 r5 H* B
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。) b/ ]  N* L# r+ a% M, ~6 ~

# J! }, z9 M. s7 ]: e. _5 p至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)8 m! b; D( X. {/ ^2 {7 V, H

' ^8 R- O: F; `6 G$ X& ?8 d! E+ U(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)- I  ?, f) }1 o, `" b" o: r! k/ e7 Z+ J

% ^, ]- @1 z5 J1 |; i1 g# L
        std::vector < float > vec1(N);
& _# X; z, T  `% b        std::vector < float > vec2(N);2 Q! p8 p% f0 k% L
        float* b1 = new float[N];
$ L2 V$ p! m4 W. O( e        float* b2 = new float[N];
. Q4 }# B5 Q$ ?+ u2 i9 H- a7 F3 g, k; T# g6 j) j( f: D5 R! O
        for (int j = 0; j < 6000; j++)
3 a8 F* R+ C, h* j7 ]6 g        {) r. a  U0 h2 Y8 I
                std::generate(vec1.begin(), vec1.end(), []() {
" h/ Q) S4 V. ?+ b4 _, [                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
& F$ E% @: z3 a( U% C5 t9 g                        });1 B; R  F: ]3 w9 S3 ~: X. J
9 `- Z1 _1 U, n% s$ e6 r
                std::generate(vec2.begin(), vec2.end(), []() {' y4 n# y6 F# E$ R+ ~
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;1 q( m2 a( L! {6 Z
                        });0 W7 i! i4 I7 [. ^5 S

5 j; ]# e+ J! u9 V( U; J! C9 c                for (size_t jj = 0; jj < vec1.size(); jj++)- [, Y+ n% e  K
                {
  {& N) \  ^4 F9 _( b6 A) |- M                        b1[jj] = vec1[jj];3 M1 i0 \5 f8 M& P6 }9 B9 d
                }& z1 E1 H/ |$ J0 t2 j# Z
% F5 ^# I, W/ k  N! D  i
                for (size_t jj = 0; jj < vec2.size(); jj++)4 B- f3 h# v+ ~) T+ B8 Q3 s  q
                {/ }+ L  A0 T. `5 T4 b; w
                        b2[jj] = vec2[jj];- G3 O1 j# ?0 s
                }
8 l) w  i5 D6 [' P1 A+ ~/ r* x
: v  ^; C8 Z9 b# N! z                //Method - 1  N=100000 247s  
2 y" B5 J9 A5 ]6 |2 u! b0 Z                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
# b( \3 p! E9 w3 S( R                                
6 d: o) W1 D" A! ~7 \4 ]& w                //Method - 2  N=100000  237s. [' _! s  C! S" M+ n
                /*7 ~5 e! T- N/ r, E( `; ]
                for (int jj = 0; jj < N ; jj++); l9 @' L0 ?: z5 X1 Q$ |: @8 y
                {. W% j2 V3 Y) O7 p: X) v
                        fresult += vec1[jj] * vec2[jj];- _! `2 y0 [4 p  K. O- S
                }5 q& b! P  K& L. e1 s, Z2 L
                */+ A# W$ d2 \% c/ K0 u2 h9 W
                                7 B7 p' ?1 j+ u' v3 E
                //Method - 3  N=100000 204s
2 N" _  _8 c, U1 }9 h1 S: \                /*/ S6 [9 U3 r* N. b( Q" p$ y
                for (int jj = 0; jj < N; jj++)
1 V$ S1 |. O' _$ b                {. \% k' }- Z$ u& p0 C
                        fresult += b1[jj] * b2[jj];
& A  w* P  U+ J                }! v! A( h+ j4 p6 Z" d- y# @4 z
                */9 M; P  U" A! Z8 Y/ m
* }; \7 ]- t8 {) Z7 r* y
                //Method - 4   202s2 T/ Y  B' j/ h* Y
                /*- y% _; X+ Z% N  r% y- `
                for (int jj = 0; jj < N; jj++)$ O/ t5 D0 ^  W
                {
# X, p/ u) Y  z. x                        
' F2 U( I6 J6 L3 A& e( I                }
: L' j& r3 k) E# g4 o% j2 ^                */2 c/ ~& a" i( `" Z5 j
                //comment out all methods, N=100000  202s                0 m$ {, {6 @- C# A, N
        }
* {7 X: b5 |* D: J' b: k: \
# s: l: s$ e& ~        delete []b1;5 \1 F1 G3 x+ W: O
        delete []b2;
- Y* @; A; u9 U, P. p

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?) a! i; g5 r1 d2 B
! Y/ m: l; |2 y- q2 ^( Y7 `
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
4 w: P7 C% {. ?. A
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15, C5 O$ Y, V8 F# g) [! T
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
2 H. }% k& N# H8 t7 s9 t- A/ [( `7 k/ v/ s# ~) C
你第二个试验里面的j在循环里面又重新定义 ...
3 Z) K% u6 N$ f+ D
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL6 h9 ?3 l1 y" V1 h

  z9 L1 L' O0 i5 K8 U不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
& L4 x4 A) r* B' K4 L内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL: x- S* J' l! M# |# M% _
9 b* G1 q6 E7 z& ?) o9 O0 r- O
不和它 ...

* S9 A" Q' J- X9 R! p- @9 r5 Z0 X
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
7 d5 {  H7 |. N5 x9 _  X& R后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:545 L$ A2 s: D' y3 {4 q
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; b  \3 p; y' |0 ^( d/ R  d{
, ]1 r) L6 s% K( B  T9 P        comp temp, xtimesy;

* K/ H* g9 s/ F4 A+ N5 a: m% f1 I$ V* h这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
. {& f$ n; i; O; x% k内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
# `7 ~, M$ r5 iVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30$ U  v  V( e7 Y6 B$ c7 C
理了理思路,重新做了一个测试。0 B. U2 I4 S- |) Q, g8 k1 |
做了两个 vector 和 两个 float *, 都长 100000
4 V, ~7 q/ R* Z1 K% W7 N! K外循环 6000,里面先做随 ...
' A, z9 p+ x. h
这个时间是从哪里开始算的?
/ S% b/ i. b  `5 p7 b0 D我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
. K7 C& V+ D7 J4 p6 u7 e按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
+ z/ T: n6 |8 d2 A3 M) I% h这个时间是从哪里开始算的?
1 H- G% \0 l* D# K7 J6 L( d我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& Z+ y5 b  w0 H% X+ C
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。0 D2 z) L# l# w0 f8 y- P
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
: [# t0 x, t! i: ]3 |3 \与此对应用数组(指针)花了2S  Q$ N" I' H% P7 `
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54/ U' Y5 N3 x: n9 d2 F' M9 {2 u8 h$ e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
8 J+ {. u2 a/ n" k- t7 Q! G{
% h7 i) d/ K' ~        comp temp, xtimesy;

; Z1 \+ a8 x* k0 d. V3 A& K- E我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
5 G8 q( P3 [, f, Q5 h. [: Q" c4 ]3 {5 M; |

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29" c# z1 n$ r; m4 y0 s
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
6 X' X) w" F8 o3 T* Y
; N7 U  S% l9 D/ C% E* s) c+ u" f ...

1 M% d8 a) m1 D2 i6 r你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
8 |# f- b) v% a# x3 |9 \0 I; p4 d' S$ d! D! T
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 / U& }) w0 Z& T# @, ~3 m
0 N- B, K* x1 _, ~; L6 a! V
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
' A. q# h2 R2 X' ~& v/ ]# i有空时我会试试 SIMD和并行,看看能提高多少。
7 |) I4 m9 Y) B; l7 M, U, U过去7、8 年没有正经用C++ 写过东西,没有 sense 了 * i2 ]. k0 \4 P* ^
谢谢大家的讨论,I learded a lot.  红包已发  
: T8 W- X$ X. C: `0 i& t
0 |4 t6 O: m. i, r8 Z4 R& J" \0 W; a( t; T% I) E3 ]
3 O1 R5 v+ K+ U. p) x! w. b1 J9 A
/ c" M& _3 F5 G0 r' M





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