爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?6 K7 I/ ^# O2 i; E5 c

8 s) o; w) r3 {- A自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。9 K; m8 C: @9 t! G4 Y
# C9 U) O  M  M% h3 h/ U* c$ r
速度优化问题真的很有意思啊。
5 \$ n& B- e3 J6 m
& ~- ^, Z' R" |2 C" Z欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?% [/ b$ N2 M  a
把代码贴上来看看?( t3 L8 c  d- Y0 i  D4 t; }/ z* ~

! I, |3 V5 j( M2 m, |: w8 T# n$ R难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
! Y9 l/ X" r& Z9 D  g, M* D) ~- p0 V
数值分析 发表于 2022-9-24 23:042 P, f- N4 d9 G% i! P
拉下来?拉多少?$ ^8 S6 b% S, }& W& J
把代码贴上来看看?
/ Q+ Y7 z* l% i, B4 C

% K9 B' j# u/ P* Wvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( e- h: l2 R$ m{
  j8 B% [* e: w4 R" s( ~        comp temp, xtimesy;9 w( P. j( ~6 D
        xtimesy.re = 0;
# g5 _7 c  G- B! M3 N7 v' [        xtimesy.im = 0;' K/ f. u) A7 A# L% l9 ~
        int j0 = lenB - 1;) g4 m4 U% G7 u! k7 _
        int    i, j, i1, reali;8 k4 u' @% w4 Q/ ?- k1 D9 m
        if (lenA % 2 == 1)
( j) \# i0 m* f5 Z8 k4 s                reali = lenA + 1;
8 r2 r# [% W! R( H        else
$ k8 x& f) M  i4 z$ K3 o) G                reali = lenA;- X9 X, w5 C# \" }
        reali /= 2;4 i: U! w5 j2 _& C, B6 m8 I; D

$ y7 _. [( r0 R' u3 b) Y+ p        int nconv = reali + lenB;
$ a% b, b0 C3 z! p( s1 i        //#pragma omp parallel for
# ~' V' R% N  ]5 x8 ]        for (i = reali; i < nconv; i++)6 |$ M/ J8 A+ G+ \9 R
        {
: G- v3 }; X+ J% S& n                temp.re = 0;
4 U, ^# w8 M; R* D                temp.im = 0;5 B/ q( Z; o: p- X3 w
                i1 = i;
( v4 T9 `4 {* P% I2 I                for (j = j0; j >= 0; j--)
; B% r1 R- i- }$ S                {
# d- a9 M6 H5 ?2 S# b8 t$ V9 Y8 @                        /* floating date operation */
7 i8 H; Z& s0 e( J  z- ~. ^3 ]                }

  h7 m$ l( e1 Q; {        }
) H9 ]+ ]3 }. @& s}8 p. Z, x  y" s6 T) }' v
6 D( h% W8 u' O) `1 }
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
8 s6 b, r: G% v- M/ m5 t8 W; ~
1 S/ ~/ ^: d- s红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
  ]9 ?0 l3 J  Q. ~* W; t5 `/ W现在call xcorr 100次,耗时78s.( c% n1 Z0 W* b* ^
, i6 S) @( c/ d" [% I  ^& r
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 1 T, ^& J  L- o
: S! d' \) E0 C7 `

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33! B% y* E+ h+ Y9 {* k
Maybe Debug mode?
7 m+ l/ E# L' ~

6 r! }% B* E$ O# ^不应该,看我上面的回复。
* a3 V8 q6 _( }
3 W- k' Q! k- J: Y9 j% ^: Z我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 7 `  A. j6 K& A% G% t
雷达 发表于 2022-9-24 23:544 V6 c7 d4 R; f
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  ~6 B; q. u& ?+ ~{
8 c6 S0 X$ X' z8 n        comp temp, xtimesy;
# k; s2 T1 `2 ]
# g1 e7 }$ w/ H* N, \$ q! G
这个不是这么比的吧。。。
8 a& x( W3 b' l8 R, K) A2 H% k# R! T( E
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' E( x4 G( Y7 U  Y3 {
! h7 _5 W( Z/ m" r而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 $ L9 t$ @5 v0 p( s+ J# ]+ P
数值分析 发表于 2022-9-25 00:20
  o+ K' n) v& M% S6 K1 a$ l0 h这个不是这么比的吧。。。
# Z9 T9 t7 W% z2 A/ o$ {# u! b! o6 S0 ^/ G$ r3 e, Z7 T
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

5 v" N$ M* s5 i! s" I5 M2 c+ ^/ ~5 i0 }. C' z  W/ Y
有道理。7 W7 v0 K0 n; }- \" }# C& a/ ^
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。  w) s/ ?5 D% y) S9 {$ T

! M7 B5 }; x# z/ C9 S  B6 s我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46. h1 X' W8 ~  b( Q4 {. ~
有道理。
& k) T) b5 Y, R# B所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
2 Y/ c( y/ S, a7 m, v
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多! C7 F* R  z# y6 S* N( P) A$ F
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
8 f( q# p- r$ h: E6 l- [这个不是这么比的吧。。。$ k. E% U$ o8 e2 g

9 @2 h2 p  }0 H* T% ^) r您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
. h7 J1 _: i; T+ l4 B+ H
* A7 j* N% k3 Y! E: |8 q
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
. E! N* ]7 r) L
沉宝 发表于 2022-9-25 01:48
. c+ {' T: w. G: E现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
; ~/ S0 M& e- a7 n3 Z
3 O# G8 ~) Z! r6 O6 C
是的,兄台说的对。
! U. c  b& M, C, a8 ]3 ^; T7 a& ]4 }4 w% n0 _
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。( G7 H8 X, B; u$ f) M
  L. ^0 F6 v" D& T5 T
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。4 ~% t6 ~: m$ w+ n: {8 v9 ^
, V9 p- o  W* w; ~
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。; r- B2 q2 p8 w# }, K* k$ H9 y

) ^% @- e6 D2 x7 v2 T当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
3 u" D% K/ |6 o3 x$ Q# l" S
沉宝 发表于 2022-9-25 01:27
9 A# f  G& a4 `, i, \  @, _6 x你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
/ f/ I; ?# @3 E$ h

- \! j! e! M) G又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
, |8 q# W0 B% Z. }, z- P: ?; o) H
' `! E+ N0 h) `* m0 M! v, W+ m& X我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
/ i2 G. j' G: [+ [0 P8 c又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

$ B7 [  e* n  w时间差一倍的结果可以接受。
$ m; [& K& d$ E/ C
, T3 ^% a! g' P5 g; j7 Y% v& ?你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 7 W$ J# b* g% i/ L8 h1 N- T) J% b. y
雷达 发表于 2022-9-25 04:47
  V- k' D0 e5 z- d又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
5 k6 l3 W8 Y8 W* m" M6 E. H" j
: o7 B" A' S: _! H% `
/ q: J( O' J: L  e3 `: }
1 V- {) E. s+ m. n  b
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
- F* m7 D! J5 U) O8 i( O( d7 W
数值分析 发表于 2022-9-25 14:58
- ^' t7 \% f( G6 `能不能把这个也贴上来,看看和上一个有什么不同?

2 z& [9 u1 E1 E) g理了理思路,重新做了一个测试。  y) n/ C/ l/ |5 O2 j+ j4 B
做了两个 vector 和 两个 float *, 都长 1000005 \+ H9 U) p/ w4 \/ F- A: p
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
, W6 h9 n8 E8 `, }6 i0 X( n' \; [+ J! c9 D2 g
内循环试了4种方法," P, s6 s! L+ y) E# y% E4 M; V
1. 直接调用 vector inner_product 247s 4 e! e- W+ H( e0 @" W  ^
2. vector 循环点乘累加 237s! q5 J5 K) [4 Y$ \, C* ^$ |. s
3. float * 循环点乘累加 204s& B% d( d$ Z( H  j- u* L2 \+ [
4. 空循环 100000 次 202s
0 ]3 c8 h: p  x/ [- X
4 @1 @) Y) v" Z' C( V不做内循环 200s
! Z8 \, K; L& g5 L
  ^1 U7 g" i7 b5 F你昨天说的对,内循环本身占比是很小的,大头在其他处理。
- K$ [# }& p# b' u: w2 Q另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。( P$ h8 E' \- P

0 _' X: k; [2 u0 v; _至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
7 ^9 e, Y% Q" D9 k2 T& c: X
6 x: D% N4 ]  l8 U* W$ E/ k! t(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)2 |+ \8 o7 H; d& A/ D5 J
& J7 n$ D7 m4 k6 |- i0 \7 Z
        std::vector < float > vec1(N);
- m" V# ^) [- v7 ~% I# p        std::vector < float > vec2(N);# X- f5 R- k" k" y: J
        float* b1 = new float[N];' E" k1 W& D" @0 f! z
        float* b2 = new float[N];
5 b) {' s4 j; D1 v
1 L+ j; }8 w! A# R# ^6 g" q        for (int j = 0; j < 6000; j++)
, t) z% l% U% Z0 l: m# R$ Z        {. w5 E( K* M& G5 Z
                std::generate(vec1.begin(), vec1.end(), []() {/ x. I# ]$ _/ N
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;- b9 Z; K: }: q, O0 C
                        });+ w, D, b% I# d- T) J& n

1 I- M% F: z0 @. y1 C3 ]& s3 O                std::generate(vec2.begin(), vec2.end(), []() {) _; h# F7 X2 y! [; Y; C0 `
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;9 ^- [; C8 L& e" e: L( _
                        });
' V, ~  g  I; e5 r/ }2 J  s4 u" z* R0 y
                for (size_t jj = 0; jj < vec1.size(); jj++)
7 r4 y7 p3 I5 r- G- |! W; N                {" ]7 m% B) X) I- Y$ h, d% B
                        b1[jj] = vec1[jj];3 v8 a" k0 r! @# L; o. M4 f  M
                }
$ c1 \5 f# }# d0 P7 }- e9 R( r1 E
9 p: d2 G7 d+ P1 H- D. z6 I                for (size_t jj = 0; jj < vec2.size(); jj++)
) Y* B, n4 G! M8 |% P5 E6 F' m                {) f4 k7 A# Y/ x6 M8 x
                        b2[jj] = vec2[jj];
  X: c0 G4 t; _                }
, c8 \! A! R: U# D8 k- M& P/ a0 a# s$ |; Y" z3 O7 y- V
                //Method - 1  N=100000 247s  
! t) _$ o  G& @; s* I                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
; X. y! o$ d0 k: T0 X, E                                
  f/ K2 K' `4 R: Z                //Method - 2  N=100000  237s
5 t4 a6 V* ?) R) Y" \                /*: F& p9 i' E2 K6 M8 w3 j
                for (int jj = 0; jj < N ; jj++)( g% v2 X% o, L- L0 k% E
                {, }% r" _' w: y/ H3 l; m- R, x
                        fresult += vec1[jj] * vec2[jj];0 V4 D7 t& J/ R2 }5 J+ Z8 ~
                }
1 L/ N1 c0 b2 h$ J$ f# N                */- Q( ^4 G0 I7 p1 A2 s4 S/ o
                                6 ^3 ?, L7 s5 X- L5 U+ }3 s
                //Method - 3  N=100000 204s
4 T9 ]5 }. P5 |) ?$ ~1 P                /*
" ?1 I$ m* |! m8 Y: z, X5 Y, k5 E                for (int jj = 0; jj < N; jj++)' h0 z7 K- X7 O! K
                {5 s& x  k0 u( y: S8 N6 U1 P
                        fresult += b1[jj] * b2[jj];, v) b7 [% G+ N
                }
& p0 J% _2 W. ~, U/ v                */
0 d4 L9 b# B/ s& Z$ ^/ v0 _  ^1 ~8 x* W0 l$ |$ W& I# b
                //Method - 4   202s: c! F. F) K, f. e' f  J8 V! f  M4 Z
                /*
% L/ k) p2 W( e5 m                for (int jj = 0; jj < N; jj++)% c4 A- T$ L& s, L  ^
                {
" w' F0 ~: i5 ~  t; K, d( W                        
) m! U, b' [( ~4 V                }* q7 V. ]7 m: {" J3 a+ V, G; D- k
                */
' f/ H! D& v. w                //comment out all methods, N=100000  202s                ; Q( j1 s" j; n# ]1 ]
        }' h3 Y* z9 |, k( D" a
4 K; y6 b; N) O) R6 `
        delete []b1;
5 l& D" N1 l" P. X        delete []b2;
/ Z: k4 O* @4 D9 t

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?9 U& B/ _5 o8 I5 h

3 V/ ^$ P9 ]  Y你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?+ o$ l& Z6 x- X. ~

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
+ W* w! }* V+ H+ u瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
1 I0 t2 ], U" T5 s8 I6 J' o
, V; [: z% O# v3 K8 o你第二个试验里面的j在循环里面又重新定义 ...
: |- e3 Q" \. ]* c2 \* X
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
$ A# `& T( s  \" _. Q  s% B& A: x, q  \7 t# w
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16# O8 N0 N& p- K$ g& }% n% _
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL- e6 X  X  I3 _6 h
& x! S& F8 \: M  w& ^: `6 \- t
不和它 ...
3 b, ?2 T; g6 Y5 N5 R+ a7 D4 L) ~

  L' `6 v: r3 L% q# Y  R不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。( }; p. x7 n) }9 M7 ~7 z+ C
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
2 a6 y, O; R% K- Gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  T) r+ b3 B- G8 h: b{
% L5 i5 f& {2 k  u2 O7 w1 f4 {        comp temp, xtimesy;

( n. }; E% C. J- F( s这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
, }4 ?: a+ T( V0 G* v内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?8 F6 d  _$ F: c
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30; O5 E! Q7 g/ y' v
理了理思路,重新做了一个测试。4 F3 [8 l! [- Z
做了两个 vector 和 两个 float *, 都长 100000
. O# X0 R' |; s; P6 L# v. i0 l外循环 6000,里面先做随 ...
4 S( e7 `* }7 g
这个时间是从哪里开始算的?
" I+ M! }2 k% M/ }我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。( B8 ]' o; u/ u8 Z8 T0 W( T
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
& s' M0 w0 e% X( k1 Q% P这个时间是从哪里开始算的?9 u- B6 L9 q5 o% Y/ g  `. @
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
  B1 L9 w, u- |4 k3 f- K
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
% V, u+ C* n) r" y2 b4 Z你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
4 \8 m6 y% q% z, s# S  S* X4 a( l与此对应用数组(指针)花了2S
  f& b+ x5 j6 n, T你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54$ E4 F7 s$ Q- A# ]8 `  u% W# o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ _% `. p- }/ W5 V
{  {! ^6 O8 C* w
        comp temp, xtimesy;
& d7 ~+ ?4 d! Z# v
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗/ R0 `$ V/ N6 q. @( q6 x. M

' F9 T2 L; ~! |% |: `
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
# m( ?! d  y; D$ }7 {0 T我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
! U7 R  V2 ?& N/ U, l# W
+ f# W1 ~) f  D5 c9 [ ...

/ x. L1 f! t4 M' r' _: {. n你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
  N2 }  v" }( Z7 l( Z
2 h8 _8 q$ R; M$ H, L/ C0 N雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 3 I0 k  U2 T% Q& K
1 C, L2 T( v3 m- y) b- T0 v
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
& @. W7 K& {5 ?4 T有空时我会试试 SIMD和并行,看看能提高多少。! ~% b. r( h! c2 P
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
4 ]2 r+ I. p5 q9 o4 A谢谢大家的讨论,I learded a lot.  红包已发  ! t3 z5 T7 _1 v7 _2 g# e

- f" h6 c  f2 m' M/ a  A3 E4 B+ T5 p0 m, n. {! P5 ]
/ d. _/ |9 T! }& y# y

( x% [& T: x$ _: b+ L




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