爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
6 F+ J' j( e) d- U3 p( }' v' p* \5 n" g( M
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。! C# K* M2 Y, b7 Z4 j) {9 q1 O
1 u( l% g  O" N3 v# ^! v, @# \2 E9 h
速度优化问题真的很有意思啊。7 }3 I. d- b- R$ _8 m
" G* L; v# ?9 P7 ^
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?2 D7 |9 n5 V" V
把代码贴上来看看?" S' @; }- y, B% N7 E, I+ Q

7 u# l5 i8 A! C- m难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 : \( `, _' k4 {/ a
数值分析 发表于 2022-9-24 23:04$ s, p; E* f+ V/ a
拉下来?拉多少?- G2 |4 w  ?! l, w% X
把代码贴上来看看?

6 Y) a6 d( J) y/ a2 [* u
: R& k' Q) D4 w" ]  r4 c4 l* B5 svoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
. d- V/ r- ]* T% A, y( ?{  {% c& d6 y/ h& Y9 e
        comp temp, xtimesy;
+ a, |  g: c) P1 X1 H% A4 b        xtimesy.re = 0;
( e* W4 u& a% d# d9 o        xtimesy.im = 0;
: U* y4 _. p5 X' ?8 C7 E        int j0 = lenB - 1;" f: ^4 f+ I6 @
        int    i, j, i1, reali;
$ _; \3 y% s+ g. e8 Q8 S/ X        if (lenA % 2 == 1)
: W) u% {/ s' _, o5 I2 e& l                reali = lenA + 1;3 }  ]" y% b$ ^7 m
        else
7 q, i0 P' V* W" D0 y. M0 J                reali = lenA;- n& y/ o, d/ G7 J6 h
        reali /= 2;* S1 `% i3 y3 r/ w' j" X/ ~* @6 ]- h

$ u" N$ k/ U4 R7 T3 K$ @5 S        int nconv = reali + lenB;& }& s1 P" V' g% f+ M& o' W
        //#pragma omp parallel for
* n" o0 S2 W( s) p+ _        for (i = reali; i < nconv; i++)" k/ w. ?! R% b4 [! C. k
        {
; v# Z. q5 }) X                temp.re = 0;! k. @4 e- [! s, K. N
                temp.im = 0;
5 f* [& S7 n: r: ^' \* ?0 i  [                i1 = i;
; _( \5 x: u' ~9 J* i; y                for (j = j0; j >= 0; j--)
$ A' n) R4 t; b; F3 c6 K                {% q$ o8 U. z7 r$ w8 Z
                        /* floating date operation */
  [7 i! z; c  E0 q$ l                }
* n% @6 l) \5 A$ k  x
        }
  y" M  N+ ^) Y/ \; m1 A}
+ Y" }7 T/ a8 ~
6 M# c$ W+ P% K5 V: @xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样; D0 Y2 r0 j) p) |) e* F5 B/ I4 }

5 N0 m( |! _- f; y3 m红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
8 _$ h+ [' n* S: W2 x; t7 W现在call xcorr 100次,耗时78s./ S+ ~" T, C7 u7 X1 }8 f% V

' a- q4 X/ Z& Q# y如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. $ }1 {0 X+ `- {, A8 t2 u8 n

" s+ O' Z$ G# S! H: I& x0 F
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33! c4 ]% S- Y, {; M$ M1 o
Maybe Debug mode?

# r  B% j" B, T- X
4 Z* F; K6 \! {" \8 B6 c$ k不应该,看我上面的回复。8 @! m; U: t2 a. B! S) R
) M7 R; q: m) V. B9 @6 A
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
% @$ u; u% l! _% Y
雷达 发表于 2022-9-24 23:54; W4 Z  o* Z/ e2 `, ?
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)3 \6 z! ^) }  n& ^
{
0 T0 L1 q  M9 }3 l) `! c        comp temp, xtimesy;

: \; H* ~0 `; m3 U8 i4 v: x. W0 K0 r& \
这个不是这么比的吧。。。# D0 n/ U& F  e# ]: M7 ]
) e/ o- f7 l/ |9 y
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' h" ~0 x" J5 w: N
  L+ q- H! d( g# U& z3 s而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 : C! o  g) y9 e+ k. q2 T/ i
数值分析 发表于 2022-9-25 00:20
* w, Y' p$ _: S* Z0 v0 G: z这个不是这么比的吧。。。& d( U' ]# H7 q! W+ W

2 a' o; T- p2 j* W4 e您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
% p+ {" Z' g7 R! t8 w) S- s9 h  q
! l! r# W3 i4 w
有道理。- Q( O+ a. H% [0 l7 ]
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。" w6 |5 M5 v6 G  U
. C0 a  U3 \/ }, w/ e  j. D
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:467 [. [1 j/ T) Q5 d& S: f  {! _
有道理。; R4 J  }, v$ y4 q+ N- P
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

( ^' N" `9 c2 v, h6 t$ y; x" t1 G你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多1 }9 Y6 E7 k9 E9 [( H+ Q( w4 o
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:208 Y  U- z0 Q; m  T8 S
这个不是这么比的吧。。。# G0 g1 }1 I" l2 k; i" B
: @& @' {( X9 J
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
4 c. a1 ]  n* ~2 d' B7 U) d

. L  r; k: J6 y$ M! e, E" Z- i现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
% H$ [  u& i4 W/ z7 f
沉宝 发表于 2022-9-25 01:489 R4 o! F0 J; m% f) [, ^
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

5 [( a9 d0 p  g) m6 i" S# A5 P- }' w( [3 ?- k: n3 }* C* [0 @4 V
是的,兄台说的对。
1 s6 K1 ], T# h: ?7 h5 [
+ o- c1 e; Z/ L8 E/ x) u! O6 V9 O其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
& ]" Q, W+ L: W" L9 E/ e# }3 ]  K/ Q
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
0 [7 v! V7 j5 G
2 T' _3 S7 l0 w比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。& W, u6 G% ~; y7 k

; r* T/ l6 `: }$ \5 q$ @当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
7 |5 n/ J+ f$ W+ P7 L+ E* `- {
沉宝 发表于 2022-9-25 01:27
  \: J- Y2 R$ A# C2 \' \你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

4 c! |/ `3 e* U; g; v
, k) o  \7 Q+ o4 F- M& A" H又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
, J& `2 ~# H7 g8 P7 z/ F4 [. e' k1 m4 m- J, u  g, y
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:478 a$ S! v3 |- U; F; ^. @8 {' N
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

5 _' X, }4 f- R# |( F  I时间差一倍的结果可以接受。
$ i+ Q2 i& j; F
& K8 R9 m0 E* h3 K7 w你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
3 I9 l! r/ }( s% Q! E
雷达 发表于 2022-9-25 04:47
1 P* G. b) X  v5 m9 o  ?& |又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
, E" x) r& G6 ^( W# Z, G

0 [5 w9 e) z- P4 ~& G% o5 f9 x
5 e) J- `' [. {' ^+ k0 f+ J0 v! U3 X
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 # H- t: N. M3 y, l( }* \
数值分析 发表于 2022-9-25 14:58
8 M$ Z( Y2 i) s1 s' ^. M能不能把这个也贴上来,看看和上一个有什么不同?
8 l: w6 J/ @$ i) R5 f
理了理思路,重新做了一个测试。; X# e5 a% K0 F# P
做了两个 vector 和 两个 float *, 都长 100000
" [2 O' @. o9 y3 t, e4 X0 ]) k外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.2 X$ S% |  |2 g( `$ n& E

3 u$ d. [( S/ b+ j# L! H$ \6 i内循环试了4种方法,
! q  P/ Y( v! D- P+ x1. 直接调用 vector inner_product 247s
& n0 v/ l6 Z. A3 @2. vector 循环点乘累加 237s
2 q& G; v" A+ u$ t# C3 B! y3. float * 循环点乘累加 204s
- i/ N0 H; @& M- @6 g3 ]1 v$ I+ V) V7 z4. 空循环 100000 次 202s
) S8 t, G2 F: d4 b, Z; \0 `
5 P! t# F5 s0 v不做内循环 200s0 u. k3 I4 B9 o& B

  b1 k' G) D+ C" P你昨天说的对,内循环本身占比是很小的,大头在其他处理。
  J5 m1 ~, W% Y4 t! o+ A9 g另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
5 i$ S  \5 f5 g! Y6 B! W1 d+ [* G$ a: _5 Y3 E7 |/ |
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
3 d0 z4 S  g" J3 a! O* b' `$ o$ M" g3 O/ D  o8 S
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
6 Z6 a- Z& N# e/ q* @: S9 n5 S, l: K7 U
        std::vector < float > vec1(N);
' u4 ^1 ]' h! e  x( Y; ?        std::vector < float > vec2(N);% N5 H+ v$ H) K, f' |; p* E0 Y5 g
        float* b1 = new float[N];
) G; e* P" ^& |- e        float* b2 = new float[N];# b- Y1 x6 T$ x1 l! ?

  U, A" d$ |! ~  E( b3 Z        for (int j = 0; j < 6000; j++)
, f# t; l' ~" C7 O5 B8 x5 z$ `        {# g' X; p  g+ l3 ?+ b
                std::generate(vec1.begin(), vec1.end(), []() {
; b- w& c3 W* z. Z/ W5 k. \                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;4 w+ z+ }9 C- A+ G/ W2 z# N
                        });$ L! A5 V' b5 f

3 f9 d6 d+ E. ]. P+ ]4 D4 e( H+ j5 K2 x                std::generate(vec2.begin(), vec2.end(), []() {$ D  I- Q  n# A9 ~! G
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
( J8 e( @7 @' d( Y) `! E                        });# B& f8 I: d7 J/ W, I& b5 E
9 G' e3 N2 T( v2 l9 k4 k
                for (size_t jj = 0; jj < vec1.size(); jj++)" o, \9 U" \3 d  J. s
                {
$ [! t- ~$ x0 P( ^, I                        b1[jj] = vec1[jj];
$ a* _, v# R8 D. f8 F. G% A- N# q                }
0 B# }2 _; N# J" o4 x; p' b. D+ G# Y7 d+ f( L+ z7 N
                for (size_t jj = 0; jj < vec2.size(); jj++)# L' r( J1 I) l$ C
                {
; |6 g* E- v4 j' }# r2 x/ V                        b2[jj] = vec2[jj];4 z  N$ Q) U' o" d  d8 G- q  S
                }" p" {1 k$ B) c" S* e

0 T7 n/ }2 H" @/ p/ `8 B                //Method - 1  N=100000 247s  $ h) w  S% |  c6 v# G2 v5 m
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);1 W$ a7 T' t, G+ Q4 s
                                
: f" @0 {! O/ f9 G# k) L& h' p                //Method - 2  N=100000  237s+ ]- A7 H) N4 |
                /*
4 }1 o* ^2 _, X6 u. u1 _' F: S                for (int jj = 0; jj < N ; jj++)- V' r* W  @5 Y$ Z. @7 i( I
                {6 y7 F6 G: P  L
                        fresult += vec1[jj] * vec2[jj];6 F1 K; l7 o; V
                }+ t5 N2 z5 |' ?9 H5 ]# L& l
                */
! k4 N2 z+ O6 Z* Z( i                                
2 U: f0 z0 O' r0 W5 c5 t3 m                //Method - 3  N=100000 204s
0 _, e- U/ X5 g& |; r! e+ Z                /*
) z# j0 R/ x  r8 h9 Y6 ^3 K5 u                for (int jj = 0; jj < N; jj++)2 P( v+ U: b  }* j3 h0 _
                {/ l! @7 u, x6 W  n
                        fresult += b1[jj] * b2[jj];: ~' Z% i$ I. _
                }. p- g* |: a/ N% d
                */% Z7 D0 l* k$ i0 k

1 ~; ]7 W8 R9 v" @. l8 M$ n                //Method - 4   202s, R  @9 w$ n& G; c$ }
                /*
# Y4 x& b* G( B7 g, E                for (int jj = 0; jj < N; jj++)
8 |) }. D; ~7 z* K. P6 C: g                {) r0 K  g1 t# W3 i8 o& l
                        ; Q9 y8 {- y! W
                }
4 G! h4 q: x/ o2 B0 a" J; ~7 @                */
* `# E" J! S4 G/ m                //comment out all methods, N=100000  202s                7 X; Z2 Y6 e1 }2 z
        }$ c5 W& o7 e. |" m: S" v, F4 C1 d) s# _

' X$ u, Y; Y" s; _& H        delete []b1;4 O9 I9 G9 }, j- F
        delete []b2;
7 ?* Y4 k2 h5 v6 }( u

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?4 V. S( y* E* p/ N% z0 m1 g! H
) T4 V6 E7 X6 U- j
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
% e% |& R2 Y3 `6 Q" C
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
9 \0 z& S0 l3 Z瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
( O& q7 L0 w* g" n8 Q
) Z6 H, D/ q! J  N/ `8 m- r& Y3 `你第二个试验里面的j在循环里面又重新定义 ...

8 o0 M* ]* o) s/ z内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
) T. M- A( m" V' `! [% q
% R6 a" [" M$ N不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
9 G1 D  z, A# N+ k; ]4 q' M% q内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL$ ~. S! H6 V9 \* W% H, u& T
- k7 _- @! o& X' t
不和它 ...
7 f  A4 t6 d& Z# E4 L# |

. R% H9 ?! V6 w9 o不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。$ V8 V% K* ~. l* r+ v
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:544 T  r0 }! x' d4 B
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' `! d* B7 B9 P6 ^{. r4 a( g. y/ Y
        comp temp, xtimesy;
: c/ o6 b6 P+ i8 v& ^
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。# B' d) ^" \: h: p
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
6 r1 C# d! G7 }3 V, ]VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30" W; X8 @% ?5 p0 V
理了理思路,重新做了一个测试。
- K9 I/ `0 K1 y/ t做了两个 vector 和 两个 float *, 都长 100000! p  q  @! F2 o
外循环 6000,里面先做随 ...

5 P# U5 [8 R. Q; A2 N; b' a# T9 E- f这个时间是从哪里开始算的?" h- S' h+ o) g+ G1 Y+ j
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
( {) k# f$ ?% w# f& I按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:391 a  _, l' P+ S+ q8 |2 L0 {
这个时间是从哪里开始算的?
: |' N# D- _( Z1 V我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

% ^5 N! T# v1 J0 A  w5 |9 I% R我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。% [4 ]2 e* q2 n9 n- |
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。; h9 M8 E1 W5 S* }; |
与此对应用数组(指针)花了2S  y7 ?5 `1 H# `) v2 \, T
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54& r9 s) g% f& t8 `1 V
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)/ e+ ?) c+ m) ?
{* ?6 O( ~( U3 [) P. g* ]3 @
        comp temp, xtimesy;
8 b) r6 s, P) s% D7 ]- k2 D: \1 X
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
7 D8 p$ ]" L1 A$ V( w9 j* q. }. `/ w, ?1 ^4 a; b

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29; d/ I9 \# f" I6 p0 Z
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗0 W" I) r5 V  a7 z
* x8 s* w! a" z( `
...

8 ]+ |' }( {" g; s你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。) @( B. @' `, j

, `4 j# E. n- p9 }" _% E9 C雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
8 V) k+ u2 h( T$ O" T) P
& u' y) n& s% C  ]" s. m9 i/ c是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。8 p% H# z! ?/ B* G
有空时我会试试 SIMD和并行,看看能提高多少。% c; g. G. E& D2 y" F8 j
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 & E0 s) N- V9 G5 l; {: ]
谢谢大家的讨论,I learded a lot.  红包已发  
9 _/ p/ `' N6 ]$ s8 L0 Z% E
# f, R6 c% Y: x8 d
+ P7 v1 h3 d7 ?: }
) u, W. L, p* K- T
: u/ C$ F0 I+ |, @) F




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