爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
$ E: V2 K$ }2 l% A8 j. O- F2 a* s' H1 {. p: d' r2 J1 }
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。" Q1 c: }( }" s7 B6 f! `
2 f. ~: B& @$ M9 m* ^
速度优化问题真的很有意思啊。2 T( b5 v$ N: c$ T

% U1 R. U* t) h( ^9 u7 `欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
! F1 x4 o; K1 F& d2 \6 v8 w把代码贴上来看看?
, F5 U8 k. I' H$ S. A6 O& D6 S- O4 x0 {: I' L" U- ]$ q
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ! a' H# I5 Q* R; ?& x- Z6 K
数值分析 发表于 2022-9-24 23:04
9 R1 Y5 g& @2 b拉下来?拉多少?
2 W; H- {5 z' R7 L  b把代码贴上来看看?
' Y5 |: h/ ]/ |5 u; d- ]1 k
7 G: u0 _! V9 M% F4 p
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( e& j" t0 i& I- t* V{( i' g1 E6 q/ F1 ]+ l
        comp temp, xtimesy;3 F# M& L$ Q- [+ k
        xtimesy.re = 0;
6 t5 f) q9 Q  V- c( y9 y        xtimesy.im = 0;
! H0 u+ \2 _; m  V4 o0 F        int j0 = lenB - 1;
0 t5 P$ P. h# }1 K& h! U0 J        int    i, j, i1, reali;
9 Q$ I- S- y% i9 Q3 q        if (lenA % 2 == 1)0 ?: V7 D* X$ W' q8 u* H/ x
                reali = lenA + 1;
: K6 O' K9 P' g/ j: Y, u8 j        else" ^$ _* N+ G, l8 [
                reali = lenA;
% C0 g: y8 w9 i# L/ k; o        reali /= 2;9 ]. M( [- W/ t9 N# E$ v: `

4 h# [. i, ^+ D+ ?+ X( G        int nconv = reali + lenB;
; _. ?( Y6 r) }9 g7 g8 }0 ]7 {# V        //#pragma omp parallel for
* f4 w& W3 r0 f& H0 z5 Y- C5 ^        for (i = reali; i < nconv; i++)
: j  X( o$ M$ w3 G# {" T2 T/ i# [        {/ W4 c+ q; L$ e. C
                temp.re = 0;
1 N$ w% u3 Q" G0 p9 ^) g3 d                temp.im = 0;" d6 y2 m) {% B+ [6 y
                i1 = i;5 U* V2 x/ V' h' A
                for (j = j0; j >= 0; j--)
- W( t: @) K# `4 U0 F' o( _                {
0 [( g( ^: T4 N+ f7 C8 N. ~                        /* floating date operation *// ~0 o6 b/ n" `5 g5 B
                }

4 O& b+ O3 }# S- Y        }
4 l8 R1 [  X* H}
5 Y: M* `& X! o7 i) ^! p- G# w
8 a. K0 m8 U# ?8 m, e5 C: pxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样2 U1 }! h% O! j- y
, ^1 z+ Y- `; W
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
  g' ]/ u; Z% u* m9 y3 l( n现在call xcorr 100次,耗时78s.. ^% ^* _8 g# {+ M8 _

9 n# W  n3 }2 M3 i. m* x" ~  C8 _如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 6 d) J( p# h8 r! P. _% H
0 f4 M" z& T0 P0 G# t

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33( r) w5 k% P/ ^' }+ {" G1 H
Maybe Debug mode?
5 r3 J- a1 _$ B: ~( t6 w2 O5 a6 F8 g

3 W+ l- v" `3 }5 F- B! o) j, ]不应该,看我上面的回复。7 z& n& d9 P3 m+ P0 L. Q( m' {2 y+ Q

4 Q9 s; w  c& G9 }1 u( h/ f4 m我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
! a& I, A& m% z* [; b7 a$ ^# V0 R" ~- a
雷达 发表于 2022-9-24 23:54
4 F6 m. @4 j* b0 y. evoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 e% c0 l. s1 Z6 w$ s% U
{
. ?+ v4 Z7 n) j2 X0 {        comp temp, xtimesy;
8 B# H  {- U+ j' T1 v* X0 {) m

4 G$ U8 T, Q  t% x1 [$ b这个不是这么比的吧。。。. i7 i) k7 G; u+ a0 o

1 O9 I0 p' V! L* G; S( {' n您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
# J0 R+ u0 @/ P: R
7 b7 W# g5 f( T! c而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 7 E& w2 z6 Q4 z. \, _7 v2 w- R
数值分析 发表于 2022-9-25 00:20
9 r, p4 u$ v" m" N% \) \, S这个不是这么比的吧。。。
+ a( E$ R6 S  w8 U( v/ L; {/ q2 A2 S! N" h" |1 E* ~6 g3 G
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

" Q7 ?0 g: H6 G& ]. A4 ]0 N- j. M. `
有道理。* B1 n9 b- j% S
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。$ _  S% U2 f, T1 T: C9 j
- W$ w8 Z) Y" O* M3 b( f
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46* `. `2 W; a$ Y/ A! @% i% A
有道理。
* Z: K4 x! O2 u, M4 Z! t% u0 ~2 A所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

7 O" ]* x0 t+ k& v4 Q你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
& W2 Z4 t( n+ u8 B  ]4 k/ CWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
; N. o: n/ H1 [9 c这个不是这么比的吧。。。2 ?% b  {3 f# J' l

: F& Q- ~, ~$ x) b/ {/ j您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
. d1 D7 f1 I6 e0 }. U
+ X  X5 o6 b+ @
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
- W0 W8 }$ Y+ q: T9 R- p
沉宝 发表于 2022-9-25 01:488 _% x+ A7 s8 w% y( \$ G. d
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

  P- a7 M1 z- _5 s, B/ ^
" b2 f$ S5 Y" ~- H1 q是的,兄台说的对。
* B" \7 y/ y2 @  o2 I' p1 B
( J0 s; g) |% p  u+ p其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
% V5 J2 _1 Y; Y
9 l: g8 U% v; p/ \7 `雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
6 R4 m0 u1 m4 L0 M' l' Z# F4 V
8 Y2 W, u1 g$ O- \7 R5 _比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。: R7 a( r+ W1 }3 r& v$ i

& `2 F+ W( p8 W# }) Y8 D当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑   Y9 Y, o, d& P1 c8 |
沉宝 发表于 2022-9-25 01:27
! T  p5 @7 l4 [( X+ D# @" R0 y你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

4 k5 F, [+ p. ^- K( c% H5 ?5 U5 D! k7 P2 @, n: w
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。' L8 A9 b& Q8 j9 h. S5 K* t9 k: V
! b% i% K$ v! U8 \. x
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
3 {+ l/ i% T. [( x* z% H又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
& K0 \8 |( F% h- U0 ?* {5 [2 ~
时间差一倍的结果可以接受。
% s8 J! r' }. T5 P8 m5 W
9 V2 G3 y8 W9 Y& Z# [7 y0 g你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
" @8 y. o0 C4 H( N
雷达 发表于 2022-9-25 04:474 M; o* q6 }, s& W! ^5 @
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

: d' ?9 U% [* F" u4 ?$ j* Y) R- y' I- n: H/ q3 L/ ?

3 L; W0 Y( Y2 w" f) W/ {
$ @0 X4 k1 @5 ]" \! y能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
  ^# ^3 G) M- |/ q5 P# N
数值分析 发表于 2022-9-25 14:58, G; e4 @% `$ N" K+ G+ Y
能不能把这个也贴上来,看看和上一个有什么不同?

) s) z9 @) i0 m& U0 ^理了理思路,重新做了一个测试。0 _6 t5 j& U6 u) G( v# n/ D; F
做了两个 vector 和 两个 float *, 都长 1000005 p) S; G2 Z# }: Z2 w
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
7 Y" B; Y0 c. c# i9 D' f5 u2 T( @+ k2 q) p( i# J
内循环试了4种方法,% {7 G8 n2 I3 K8 ^4 \6 U
1. 直接调用 vector inner_product 247s ! t- R& E! @  z- o/ `. J- z: a: \  x
2. vector 循环点乘累加 237s
& W/ g* ^5 G7 B, P6 R3. float * 循环点乘累加 204s/ [" x. g) q+ \
4. 空循环 100000 次 202s- }+ f; v4 _6 Q6 j: n

! Y0 W+ P3 ?' B2 s* {/ p3 c( ^1 o不做内循环 200s
& y3 S$ a  A2 [
8 B- w4 V) f9 [; x0 x你昨天说的对,内循环本身占比是很小的,大头在其他处理。/ F; I4 t! N! _9 w/ _3 R
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。6 x0 f4 |7 W2 q% t; C8 p5 M! T9 d

2 A, [+ n% c* g+ f. `- ]7 Y: J& z至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% z  j* w  {+ O5 z4 N# q7 z2 g% t

3 k/ J' i! \" B(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
, _$ I* v/ }4 j( S
3 O  R% C7 K  D  W/ e
        std::vector < float > vec1(N);
: v* {  \( G, R' {" O3 C7 B3 q        std::vector < float > vec2(N);# m" x  N- t* u+ j( P) D
        float* b1 = new float[N];
" D+ }' B0 _5 n. `0 {% k        float* b2 = new float[N];
3 y  j+ u* n6 Z( |# b: H3 g" f
9 U' l  S% {, g        for (int j = 0; j < 6000; j++)0 g' i. d% k, k) J* q7 m
        {
6 s& M. Y( b) Y7 C$ @  w                std::generate(vec1.begin(), vec1.end(), []() {
+ }/ @; R6 j, P4 h3 P% C                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;9 e. W% T8 N8 g$ M. o
                        });
& a% u% ]6 C/ ]  r! u' b# a; Q# [# Z9 M- _
                std::generate(vec2.begin(), vec2.end(), []() {0 e  O6 y/ U9 W9 q- l
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;: M  E# B$ b0 ~; _! p. _
                        });
) e+ _1 K2 m9 V) L' S. [: e4 J  U, u/ l+ o# L6 G8 K$ T' D
                for (size_t jj = 0; jj < vec1.size(); jj++)
1 t. C' P% X9 ^! ?3 u0 s) X                {8 H' x5 ^4 ]% U
                        b1[jj] = vec1[jj];
" y" G6 B* v& U/ u                }
+ P; N0 ^+ c6 M7 a+ d( Y9 e. e- i
6 J+ `1 M( r" P2 ~! D) H! W& }                for (size_t jj = 0; jj < vec2.size(); jj++)  ~- d5 i; U1 \: R% G4 [, P
                {$ b3 s. `  ?' D
                        b2[jj] = vec2[jj];3 S9 N% p$ w# _# u' b8 n
                }
1 _% A! w8 B2 G  r: O2 m& b! @/ e! ~
                //Method - 1  N=100000 247s  ) G) X; {  n! ^* X
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);3 f5 N4 @  t: u6 q7 [7 b
                                
$ _  }; H. Z7 R1 M7 V                //Method - 2  N=100000  237s6 s# x8 W& A( `$ R
                /*1 D3 }: i" e' I/ `
                for (int jj = 0; jj < N ; jj++)
5 @# c2 T& l  L& y1 H                {7 H: J* ^: Q5 [+ p) B$ x
                        fresult += vec1[jj] * vec2[jj];% _% V& {' A$ f4 ]+ E, i
                }
6 U: h7 U) ~, L( [- d                */6 |0 R2 i& e+ s( a3 E" o& z  }8 t
                                
% a. ]$ q5 D6 m# F                //Method - 3  N=100000 204s/ ^" p, N' t7 Q4 ]
                /*" w0 o( u; n( W0 h0 O" G0 j
                for (int jj = 0; jj < N; jj++)2 f+ b7 w* ~3 K: k7 r
                {5 T$ v- [, D3 J. \$ O0 B4 t
                        fresult += b1[jj] * b2[jj];5 X6 b5 |) k5 S/ Q
                }
% i; U) @/ w; c2 Y- o- ]' f                */
* G; C% [, w: ]& P: z. {1 x5 G' c; r9 Z+ [
                //Method - 4   202s. c& W: A2 T5 U
                /*. A: w, t5 {$ G
                for (int jj = 0; jj < N; jj++)' c* X$ |+ o3 B0 c+ F* H% ]
                {3 S. V3 q% U4 n
                        ' K: b0 u2 ?, E0 f
                }
5 W- h. ^: d. E: T9 k; X                */
7 e4 n% N5 ~+ J7 k6 a* C                //comment out all methods, N=100000  202s               
, @& P5 Q$ B& Q' J% [3 y, \8 A        }
& s6 F4 y' n" \+ P5 V. `  T9 q
2 t$ P7 O1 ^/ n0 |( C5 z% W' C        delete []b1;
) b! R0 o* L6 Y  a: A" ~, {        delete []b2;

8 p  a  Z  R6 J
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
9 m% M3 {$ Y5 C1 }" D5 @/ E0 ^" U' ]- ^1 R9 R7 I- @0 ^  W
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?0 a8 x& B, G; X# f* P; L

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
" v( q/ I$ c+ E, F4 I瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?7 t, [8 d4 V9 [% Y; i

7 o* n. D$ X8 z( B你第二个试验里面的j在循环里面又重新定义 ...

! v5 u) X2 Y2 e. B, ~$ [内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
9 I4 b9 I% q' i  B) C3 i1 s
6 s- [' R" R3 {不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16( \( ~+ e6 G7 l" o- y
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
; o) p% b" `1 k/ x7 ?! A( O& d; D
不和它 ...

+ r- z. G& f" [- T0 \' f0 F% l1 I) A& M# W9 U  k
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。0 y- n6 X& K* \9 i$ B& J
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
6 u3 ~/ J% @  J0 {+ qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)/ r- N& u3 Q3 |" p$ a
{
- u6 o- }" t4 \7 a        comp temp, xtimesy;

9 \/ [7 s. J" y- k这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
( a+ y4 Z8 L! z; m( `" n内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?1 {) U$ ?/ B8 C" j
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30* @1 d, a5 T/ `- D% g- R/ f$ b  @
理了理思路,重新做了一个测试。1 s1 D: @! x8 E7 f: q3 B- |
做了两个 vector 和 两个 float *, 都长 100000% `6 d: W$ \) k! o
外循环 6000,里面先做随 ...

5 [( Z6 y( [6 k1 s# h+ \" q这个时间是从哪里开始算的?
  Z3 j9 f2 }8 z2 o2 n2 L+ L我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
! F- ]' Y+ i! h+ H2 N8 u1 [按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
* |5 g$ b1 D- S( l这个时间是从哪里开始算的?% Q- I. P( I" k
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
" W" f2 O4 z: {$ H( [
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。- k: h# X- `9 D- W5 v* h
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。0 {: F, S- t- g- Y6 j$ z9 ^
与此对应用数组(指针)花了2S) g( j2 z' }6 @
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
( ^/ n2 A8 C& Q( o' n# U& W) fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB), d0 P9 A7 j) e4 q( i/ i2 p
{
/ _9 ^$ o5 r. B$ J        comp temp, xtimesy;

, H5 l" V4 o1 A2 q: c: n! S: v我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
! h: F  m* C$ B) b* ~$ n
, y, C8 j( b% h& S
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
" r3 u  T% F  ~, s* x6 y* N我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
5 _8 ], D, u% g. e1 V$ p# f$ d2 S
5 _6 Q3 |' M6 \ ...
+ L; t1 F% x* ]! r
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
) Z. K0 d0 z, I1 X' T5 z9 k- ?9 e2 H
9 Y- O# G/ U' ?. |雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 % i2 g% B- z+ b

6 p+ G; Y* g. p是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。: `3 z' D! y' V9 |8 L6 @" B; j
有空时我会试试 SIMD和并行,看看能提高多少。
& [' @  b5 T8 x% i! R过去7、8 年没有正经用C++ 写过东西,没有 sense 了
* d+ \$ T# A+ {- u/ y& u谢谢大家的讨论,I learded a lot.  红包已发  
3 b+ g. x' ]2 Q! `/ f
8 n* _, {5 X% C/ j
0 d8 }) I* l" G  @: e! J$ q( A0 u/ C+ Z: t8 ^* L
) r  {4 R& |1 a% Q- m





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