爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
# n  E8 \0 u- I' C5 B# N* x0 d, T" b7 o4 a
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。& k* Z( a/ S7 d% F. L

* q! o( p1 D5 v速度优化问题真的很有意思啊。9 o8 K5 x; i* g7 x0 W0 L! J

# m, a/ M$ Z% j6 E欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?# J, l6 V( _) l% A! `3 H/ M
把代码贴上来看看?
# u2 V2 u9 a$ q! k, k0 {3 q: U- V2 w& [' l
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
+ s6 R2 g" M# W6 [; l# \
数值分析 发表于 2022-9-24 23:04* J8 j% ^3 J3 ~. ^- N
拉下来?拉多少?
% ?# F' B2 L* h把代码贴上来看看?
+ [- r+ g& G- Y1 l

$ K1 a* Z$ l, F' ^: a# {void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* U  s. T; n2 }- J3 ^* {( I0 Z. ]{
7 Q) p9 ]  ?. w8 ]) R* t/ s5 o        comp temp, xtimesy;! B6 ?; o# Z7 i, ?. E! k& S$ S; W
        xtimesy.re = 0;6 s4 H  J3 [# A% G2 E: ]2 G
        xtimesy.im = 0;$ t0 B. A! F: r4 {) o9 Y! v
        int j0 = lenB - 1;
0 b1 ^( F" _( g( |* n- f) q3 w1 k        int    i, j, i1, reali;& G3 Q. A% `6 K1 Z3 R0 |4 [2 Y
        if (lenA % 2 == 1)( S7 }: |& n4 J) m! z
                reali = lenA + 1;7 Y! z% h2 X- B3 `. g
        else, M) Z! A7 P/ B+ H1 Y! w( A) i
                reali = lenA;
9 |. g, `3 ]4 _! s* e* g        reali /= 2;
/ d" S6 t$ j7 A3 H1 D8 @1 ~0 E) d/ j2 ]% \
        int nconv = reali + lenB;
1 [- ]$ x2 ]- S0 M# Y! D' G  n  e        //#pragma omp parallel for
5 K& U: S5 l1 ~7 E+ R5 G        for (i = reali; i < nconv; i++)
5 U/ Q1 N! R, g# q: r- x- ~        {$ V; k5 a$ k7 f( t9 \
                temp.re = 0;
& `' k% O* J$ z* D                temp.im = 0;4 p  C6 P. h) i  Q
                i1 = i;
$ Y8 V; Y& y7 H  Y- D3 g) G+ K. L# D; t                for (j = j0; j >= 0; j--)
- M9 d" ?# _$ r5 j                {
$ w: }8 h$ {  |% c) ?) J1 A                        /* floating date operation */: R0 }6 n4 ]' \! J% Y. S0 `
                }

  u, Y0 ^9 U6 q2 b; _        }. s' k& R# O. V) }
}
7 X9 ~; ]8 ^: u8 v8 o3 g5 q$ p1 a& ^9 o2 g* J. c# R
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
! V! L& ]) N6 N  T
. ~$ m0 F! {# @1 E红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。5 r" R! @  W; m9 a' V9 L) u
现在call xcorr 100次,耗时78s.# I4 ]! B" ?) J, J8 u7 D  V

  f: X. x0 a; K* i6 {! }8 N1 B如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
+ B7 g# {( M0 l( [- l5 o. A5 \' q! T! s% [" I- T

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:333 R" O4 ^% M! A9 k% ^; Y- g
Maybe Debug mode?
; M4 ^( D( [5 p8 U/ z9 B; F# m
! L" x7 {' W0 F6 j- v5 Q% y! ]
不应该,看我上面的回复。" a, [+ W% ^5 k& t. y# N

' G2 g/ ^! u  G5 i2 }5 [我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ) s% \6 Z& Y' ~( ?( `( m+ V
雷达 发表于 2022-9-24 23:54
* F- h, k0 Z) v/ ^3 C3 rvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
3 P8 e- p6 a  n9 t& q{; d0 n) C9 a7 x# m
        comp temp, xtimesy;
* n* `) a9 L7 H$ \$ |

4 d, _5 C+ H- W, ^! n这个不是这么比的吧。。。
9 `1 v8 d; l( R, j6 n$ Z* y$ E. U
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
, l7 _/ J! w% ]+ @4 }
4 f% ?+ l) a; C4 I而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
, c4 t& Y) O2 l
数值分析 发表于 2022-9-25 00:20
: c* B% G, f( |4 F这个不是这么比的吧。。。
; K* O' a# G% a: ~& N6 ?+ y7 q5 k5 p& x( o' s$ v
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

" y7 |& ?, S3 n4 ^9 v& V9 q' p' t& x. }( @
有道理。0 j+ n5 J. V2 }5 m- E
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
- [9 |- {4 Q0 Y( _+ h; U8 `/ f1 u( n+ w% L
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
+ f/ g9 O. R6 A2 W  w, ~有道理。8 i1 o$ v. |. H6 ?" ?6 B
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
8 j+ f1 E0 p& D
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
+ s; v4 H: E3 r$ YWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
( D# ]8 h8 v7 j, [0 ^$ M: O/ t这个不是这么比的吧。。。  }8 z& P% M- U' B) Q6 h
# l& b% h$ Z1 W
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

2 e& Z- H3 O8 d6 b4 V
1 S  |( T0 Q( P$ q" q( @8 o现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
1 v: n/ I2 Q3 ?( \& v, q
沉宝 发表于 2022-9-25 01:48( I' _) n( w+ Z" b5 X, y
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

3 T  H# P( p. W" g# g1 ?" \" p# T  D1 M- y& ]( @) P
是的,兄台说的对。2 L7 z0 k. ?/ |, v2 I' x: {  C
3 B& v$ n. S; O$ j' N
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
# I* Z# R+ X0 f, f! I" U5 w" T4 L# Q" R
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
' _  }, ?# s* f: H7 c3 P7 m6 q1 L, M% E3 G' W
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。0 b2 w" ~' T& R+ M# B- {

4 `. p$ Q5 G- ]" t# E$ s当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
; \7 q- \1 \- ?9 R
沉宝 发表于 2022-9-25 01:27
5 ]! j" O% Y1 ~, L0 S8 ]' i7 u你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

# l  o8 g" A+ C3 ~  p
9 a& q5 {: K( M- n3 s& ?又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
# Y: u' k$ J: K" |4 B& c
9 D( N+ c" c+ x* D4 M. W0 u我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
1 c1 m$ q2 g$ T7 c) ]1 }2 ^又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

: m5 S4 `* P0 ^2 N$ ^时间差一倍的结果可以接受。
: j6 `) s- j/ L% x0 ~. V3 _
( k% i5 \0 g( n0 t, n  `0 ~你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 $ I$ S6 w1 X! y) D7 B" R
雷达 发表于 2022-9-25 04:47
6 r1 k& O# p0 u2 ]1 M- ]又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) C* L, d" i3 C% s
1 X, Y/ m! X7 R' u+ b& Z  c, o

9 Z2 }9 D& z( ^$ I8 h" W" h6 k2 c% d
1 A8 K6 M* H% o: D  f" \' {3 h& A能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
& b! T) V1 o1 x! ^1 d: Z
数值分析 发表于 2022-9-25 14:58' J1 F  U) a- }
能不能把这个也贴上来,看看和上一个有什么不同?
4 u& ~: R( w* |* b/ ~" X
理了理思路,重新做了一个测试。
1 z' R) D- M4 m; v  ~& u: a做了两个 vector 和 两个 float *, 都长 1000006 a3 M0 [9 q" P& W& I  J8 u
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
  Q7 ~! W& N8 {- L
8 ]( t. N( x4 V; C9 \2 r内循环试了4种方法,! X) ]3 F6 H4 ~0 m3 E7 U1 ~
1. 直接调用 vector inner_product 247s % \8 B, e6 t% E' d
2. vector 循环点乘累加 237s
# V  B0 @4 R  `/ v& J0 l5 k3. float * 循环点乘累加 204s1 h: f9 W9 u, p
4. 空循环 100000 次 202s% i4 z3 f* A* U+ B, |
( J1 p, Y8 n8 ?/ X. e+ p% m
不做内循环 200s
8 j& ]( D  U+ v. e$ ]( P1 }* t5 R- s& Q2 P. j; |4 ?  o+ |
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
! a5 j" h3 k  a# b" S/ n另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
- _) m' J: m4 C5 S2 x, }9 H* K; v- b( |( t) A
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
. Q6 [0 C# F# n- }
" Y8 V( t$ N& ^2 U' X+ ?, N  n: `' l+ K(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
! v. s5 P$ k9 ~3 R
# G' k" u) H8 X
        std::vector < float > vec1(N);
' ^/ O8 ]' O: s/ k- U$ c1 q# u3 N4 ^        std::vector < float > vec2(N);0 f! e' c2 _2 ^$ ^, P0 n* E8 `2 q
        float* b1 = new float[N];# D( ]  ^2 c6 J7 j# {% E. G# I8 S
        float* b2 = new float[N];; O3 d+ z, x2 }. m, g3 d7 S

: D! Z6 F" u/ m+ ~9 E        for (int j = 0; j < 6000; j++)1 h) O+ e/ ]7 C
        {6 \. }( v, P! I) Z8 U- [2 E
                std::generate(vec1.begin(), vec1.end(), []() {
' h( v% L+ A( Q6 L9 i                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
) M4 I6 X# u% {$ m3 r8 r                        });  J  w  B3 h! q. K0 L" q( C# H

* \2 v9 s7 W. ~, A( o: T" s8 s                std::generate(vec2.begin(), vec2.end(), []() {
* z% @* q2 ~) N7 A                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
' B) g* {) D# ?) z, s                        });
% X- n0 R* C  `. E" Z* u4 c! @0 A! L* Y  u, B2 q2 r2 L% o% ?
                for (size_t jj = 0; jj < vec1.size(); jj++)+ v1 `( K, q* M7 \' w' \
                {
  c) v2 z- s0 F$ X                        b1[jj] = vec1[jj];
& |2 s. P1 q+ Y$ f$ A) D. \$ l                }  G, Z- W0 M2 j+ b8 k
: p% R7 N( w) g- T/ O
                for (size_t jj = 0; jj < vec2.size(); jj++)
- _! x  G8 s# ~0 p  ?                {
% W+ O0 |7 X$ D( L& t5 l                        b2[jj] = vec2[jj];
  a' [. {* Q: ~1 w2 Z                }8 {4 s# ]: ?0 l6 z

2 `; B* u. T/ `+ B+ R                //Method - 1  N=100000 247s  + t7 a. V7 H6 u
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
) K% @6 \: j8 T' O$ X% e( m                                # e0 ?$ o; i, Z3 @9 S/ @
                //Method - 2  N=100000  237s
0 |  [5 @; E. j1 Y/ b                /*
" p, q$ q8 C. V" C! P                for (int jj = 0; jj < N ; jj++)! X1 K0 {7 G! C! D# i
                {1 ^) @+ J# Z- C+ a
                        fresult += vec1[jj] * vec2[jj];
0 e# E. z# x5 C6 L                }
( i8 V2 o. k1 ~- T7 j, n" B                */
" z6 x0 l+ _6 Q3 `% Z/ {" j                                
% [4 `' v# k9 a/ f& P                //Method - 3  N=100000 204s" J5 ~; k' ^, m7 b$ i
                /*
: l& C$ ~7 ]& d8 c                for (int jj = 0; jj < N; jj++)4 E/ e5 M# y0 h8 g& H! \( e  ^
                {
" K: Y. Q9 D8 N4 S' i! H* K% N. R                        fresult += b1[jj] * b2[jj];
2 O! f) q1 L0 s+ ^- k                }5 G+ |6 J) T% M! F/ v/ x. G
                */
! D. \% r8 m* R8 R9 d8 s) J/ e8 x5 M' ?5 n4 T" m% b: Q9 x$ w5 @
                //Method - 4   202s
. L1 d" z7 W6 v/ g0 j  G                /*! G, Q) |' Q  q: j. e7 r. i6 ~* g& T
                for (int jj = 0; jj < N; jj++); a% y7 Q( p, G$ ^
                {
' e. ^; [8 |6 k& @" S0 f6 w* a                        
. s- e3 c' T% T" i9 x                }
( b% _; V3 m1 j                */
1 q4 d6 [- p1 e- ?' N4 M& ]                //comment out all methods, N=100000  202s                  `' m+ E, s$ P( o
        }
4 @  B2 N7 c/ S) f0 V1 L3 Y# q1 \$ G( M0 g
        delete []b1;' ]/ V0 V4 H& ^! j" m
        delete []b2;

! Q3 Z+ ]8 N( {
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
$ L2 q+ @6 y. ]% r9 @/ M8 x$ b4 t3 H0 p  Z2 T* s( T8 m) `
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
2 f* m4 p6 ]* l' `  `, _( E
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:159 V0 g5 M* C" V" ~2 i
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' I' [* k: `+ Y/ c
, e1 C6 D" ?5 k7 @你第二个试验里面的j在循环里面又重新定义 ...
- F7 w# ^, S3 a
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL: x* F& o% b' }
7 ?% }. ~" b2 p5 S$ y2 F7 I
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16) z6 |2 o8 ~! E8 X- z/ p  I
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ m' G8 z5 g- b" z6 W- Q
* s# @/ o( D" L8 A8 g. A6 t
不和它 ...
0 F3 |2 s# T& b+ |4 Q
; H+ z' E% G8 L
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。8 ^7 z2 g- T* R- J8 m' A4 W( m$ ?
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54, h; E1 Z9 Z" A" k
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 H- ?/ |# z* m' C7 P4 W1 m0 q+ G
{2 C. k* Y8 C- d$ i4 |
        comp temp, xtimesy;
8 P2 l8 |/ \& d7 o0 ]
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。, `& ~7 m( I1 _( Q- m
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
8 S6 D7 R" H3 j) D1 ]- eVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30! B: a2 r" u" s
理了理思路,重新做了一个测试。) t/ ?7 y, N5 D+ N
做了两个 vector 和 两个 float *, 都长 100000
, O( q( {" ?- s& _0 D外循环 6000,里面先做随 ...
: a7 V! z' H; K2 z0 G
这个时间是从哪里开始算的?
3 C* ]& k0 g3 S1 D' T我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。0 R6 N7 o# M2 _# A" b
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
: j3 v! D8 Q+ A/ e- Q这个时间是从哪里开始算的?
2 h! m1 b: o( B  s我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& M! E7 p5 a' y2 h+ _# K; k
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。( j6 n, E/ M3 n' [0 Y
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 b/ k# i3 F7 H5 I4 i# M7 d
与此对应用数组(指针)花了2S2 v) F+ t+ b. ^. d6 Y$ _; ~
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54) u& d6 w4 P( @
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)' M$ O, ^/ b' c. x/ `
{
% R% T7 v2 Y1 f, S$ ?        comp temp, xtimesy;

( Z' P9 E  U# i- A1 D1 F7 q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% \2 W* ]0 _" G5 f5 E
- g) S, h  R: g7 A
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
' h' ?8 B; n; \/ J; ?我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗1 d$ y4 l6 z1 _0 M- P

, o2 F0 _8 O3 `: e ...

- h/ W0 f9 J0 `2 z- g2 I" p/ [你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
$ I* o6 o* s" X! @- i$ V3 u* T  R* A* L5 @7 J8 [
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
& Y8 B: U. B2 G
# c" }. W* G* D' z5 r' B3 [8 N是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。% j) B& X: q# m5 `
有空时我会试试 SIMD和并行,看看能提高多少。
6 e4 T$ x5 V7 D过去7、8 年没有正经用C++ 写过东西,没有 sense 了 % p3 t4 g3 u6 @9 A; p
谢谢大家的讨论,I learded a lot.  红包已发  , C2 ]9 v0 H) W
  Y  ^# L9 o! L. {' ?6 \2 J

/ e+ |/ [& Q0 w, ^- u9 }$ \$ r2 `; S# }0 j- P( f5 m
, l' D# ^' ?& p9 l( I: x





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