爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
- D9 B1 }+ g  l) P
4 L: Z: I4 k8 _! ^! ^自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。. J2 ^6 {3 a5 Z2 l& O  i" ^
3 q  S5 c5 a, }" K, _
速度优化问题真的很有意思啊。
) j! x; ?. B  G* B; m9 d) a/ G  C2 n; l
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?' O. E. O/ `7 c
把代码贴上来看看?2 m/ k# D' W1 |' z

& z% \# `! e8 U; m$ g* U: Z难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 8 z9 M8 l9 o8 i7 I, R; Y  J: @
数值分析 发表于 2022-9-24 23:04
0 z) W! o* j4 Y3 d6 F' x拉下来?拉多少?
: z9 f2 g8 {% j6 ?3 z把代码贴上来看看?

5 O+ g  c1 ]: a% V( b) L! q: a" [
6 Y1 _+ x  s1 \; J) h6 @; \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 B( r, I: C+ \{: D1 A, X/ o& ?+ Q6 T
        comp temp, xtimesy;, Z' s/ O5 [0 q* k. n
        xtimesy.re = 0;
) q4 ?" \9 v4 g0 o  X3 l' _' p        xtimesy.im = 0;
. `3 V4 R4 A, o; s) `! k        int j0 = lenB - 1;& q" t6 ]8 Z4 R" T) F2 x- M
        int    i, j, i1, reali;
- O! G9 \. }- @  I3 y        if (lenA % 2 == 1)
* X+ V: Q" B- ^                reali = lenA + 1;
  }# D8 k2 \# z* Q4 z) U$ Q        else
+ y% X; }; o& m. q                reali = lenA;. ~+ W7 [4 @; d9 G1 i
        reali /= 2;& H8 `  C- _9 m) a2 W
' F$ d# Z6 w# p& \5 F, c6 H/ ^
        int nconv = reali + lenB;5 q0 q& _/ O) k; J1 G4 u  V- R
        //#pragma omp parallel for( ~' ^0 C3 E! w* M/ L" g* W
        for (i = reali; i < nconv; i++)- |) d1 w" W* L% N( y6 P- G
        {
( m1 {* G' f) e; _                temp.re = 0;
4 J& E% p  C; T2 L: W                temp.im = 0;
4 @0 @0 I% m, P# A$ w( u                i1 = i;# ?: t8 o; [7 V
                for (j = j0; j >= 0; j--)
. y& c+ E9 b8 H$ }, x                {
& {% P  S4 C0 @( o                        /* floating date operation */
7 B+ B! i* d9 d2 p) F2 ]                }
2 n9 c+ z( |% d: H
        }
1 i$ e5 e$ L- c1 J' O}$ m$ S( W- F/ B; w

) d5 r& K$ H8 i5 J9 G! yxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
- H+ D8 f# O9 `; O
" Y4 q4 v3 Z7 O, ^+ K8 w红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
  e( ]% z: y/ ^' Q现在call xcorr 100次,耗时78s.( G! S) M: }& R' O

7 W% F# A& ~; q如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ! V# X; W* ~. S2 Q) H
4 b& E# n& ~! a, I: Q6 q5 I

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
. M0 C9 j) [3 c* p$ J( M' y: hMaybe Debug mode?

- w1 \! Q6 f9 H. h
$ N: m) Y" s! C* I2 P不应该,看我上面的回复。
1 G+ u7 L& m. [$ z3 c0 n* V. j1 x7 K8 G* G6 n0 B' A* L" Q
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
# I/ S2 T3 {2 E8 B
雷达 发表于 2022-9-24 23:54: x, O' ?* ]# m$ ~" }
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)% w; \" ?6 I9 O" s. m7 a1 \
{
) b) b6 H# e" a4 `) L2 r+ ^- G        comp temp, xtimesy;

4 D& c: @, Y- q6 L3 y
8 u- H3 H6 O- i$ t" }/ e" z这个不是这么比的吧。。。) i. J% A0 C4 K5 n* ^9 {

8 a/ b" e' }- E您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。- ]8 l* B: J7 X' A4 ]% [
* h* ^6 \* l' t  _: F4 h
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
$ ^7 P! f+ r, I8 t. m. k5 A
数值分析 发表于 2022-9-25 00:20( d% G7 P0 `- X! Y3 [! r( Z7 {
这个不是这么比的吧。。。$ ~& a, G0 ^7 y1 h: q# U. F9 d
1 P/ m* X+ h$ G$ }- L; x
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 ~. E; n. T9 J4 ^* x6 l

2 Y- B2 _% U' N+ ^' G8 \有道理。+ ~1 `3 q) f7 ~* h
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。% c! x. o/ E( P$ _  ]$ b  B) ]
0 a* J5 C# `; x2 r8 R
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46/ r9 J$ |8 r* v; k) z
有道理。
+ ?3 x; Z' k/ I! S# @所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

6 D/ v2 s% e9 Z. m5 b2 h5 L你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多+ N. p+ b* b* t: k; ?/ L
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
0 X1 \  @$ j( }这个不是这么比的吧。。。
7 V5 o* f: X5 a8 x0 I7 w$ ^1 r* y9 L- M
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
. e5 L; `3 y& z; x5 [. w

2 p3 m( O3 c3 Z" o现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 ! n! `, q! `1 l& p* c1 j' |
沉宝 发表于 2022-9-25 01:48* A2 e4 ?  Y) Y: r6 V
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
1 ]+ z% q' v% X' o; q( T# _

4 N6 k. G1 E, V是的,兄台说的对。
1 Z. Y, q6 K. }! p3 w$ N8 Q% D% f' v
( y4 y2 k8 H/ m1 [. v. k0 z其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。% A' P% R, Y+ E& P/ d

  K! Z( @2 T! P8 l* i雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
( d; j2 _  i% ?! j, v3 `) ^4 I* ~# l) C- B$ ^3 D
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
6 Q. c/ `! l7 J, z$ ^. Q
, a2 x% P( v% V/ }$ x9 q! [! z当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
; ?) O5 F: J/ ]
沉宝 发表于 2022-9-25 01:27
% P+ z' w7 z, f* z" r你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

0 S' C# g6 }9 n1 o1 m  f( a7 }" S$ C3 Q& F
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。. x0 j9 i" y* _2 r4 @9 I$ k$ V
% v8 a3 c7 _- Q$ Q- {5 c
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47( w2 [& }! U# K* y0 U& _) n# P: M
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

& C$ N; u0 ~6 b; o! ^- [时间差一倍的结果可以接受。, S% {: z! [" ~$ \2 Q

0 _, L# W# k: Z" W% ]( m+ g你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 2 s3 \% F# a! j; ^+ d& H/ B% s
雷达 发表于 2022-9-25 04:47$ u- N6 i8 x) q$ Z6 m
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 U/ n6 I4 h7 |8 x' \( Q; f
1 c2 V% Q8 m! P
7 ~4 @8 {8 [0 x7 v5 J

( `. w" ]" l, Q3 J, G1 m3 d能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 : q& s% Y6 g' z6 d6 m  R; ~; {5 V
数值分析 发表于 2022-9-25 14:58
. s0 g/ W) g8 R8 S能不能把这个也贴上来,看看和上一个有什么不同?
) J( `, ?9 v: S+ x7 R$ \4 X! z% Q# W- ]
理了理思路,重新做了一个测试。% t0 L7 l$ i* k
做了两个 vector 和 两个 float *, 都长 100000
6 c& @: }0 r5 h( q+ s: ^9 Z! k& X外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.5 m5 i( F: k' R+ B. V
/ L& i: q8 h: Z( ?6 |: U/ ]0 C9 `' u
内循环试了4种方法,
/ D6 Z; `- `5 T$ N! m- t0 ^4 X; N1. 直接调用 vector inner_product 247s - {4 v. J1 r- C: b. @
2. vector 循环点乘累加 237s1 G/ m. _9 d* M5 Q1 ^% ]
3. float * 循环点乘累加 204s! N- c0 s, l/ N, v7 k
4. 空循环 100000 次 202s; F2 x) ^  |7 f0 M! O

- Z6 T+ R& c$ l, ~% O' Z不做内循环 200s
4 C% S' T+ x6 z: b" L" Q( \2 w) `4 O# ~
你昨天说的对,内循环本身占比是很小的,大头在其他处理。. L2 z0 P3 Y0 }
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。4 |4 Y7 _0 ]7 Q$ L. @" [2 B! f: v! K- X

% T5 |* i* ~) f至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 U3 `) \; v9 A4 U

: q; h6 ^7 w  u( n(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
6 Q/ P9 o# ~& L* J) t( q# A9 k: ^4 C  H: z& w: \0 \6 y
        std::vector < float > vec1(N);
3 k- o: L2 V1 [) e9 N2 A        std::vector < float > vec2(N);6 p( H) X( W5 T1 O( ^
        float* b1 = new float[N];
5 m" k, U) _1 Z3 C3 o% u        float* b2 = new float[N];0 `/ A" L9 O4 M! E1 a
. a! y5 z6 k4 I
        for (int j = 0; j < 6000; j++)# U0 K; \! N( e2 v; A
        {
/ r# i; W1 ^+ z4 |6 s                std::generate(vec1.begin(), vec1.end(), []() {
) l9 C$ A( h( F# J9 E9 O                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;$ P, X# _% _  T! ~+ A! l# P+ A
                        });' j2 F- D) W4 j+ y9 t7 ?

8 t; T4 W! [, T4 _                std::generate(vec2.begin(), vec2.end(), []() {
$ }4 s& ~$ @3 y, r$ D: Z                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;3 b, _' g* h2 Q! J/ t
                        });! I) W" X& b$ @0 z- Z& K

% {+ m9 t8 M3 v% M9 I, S* H/ U4 B                for (size_t jj = 0; jj < vec1.size(); jj++)
* X( c" X2 R' V4 {# q# x                {
4 i5 o! m0 q8 O- H! q2 q                        b1[jj] = vec1[jj];
, Y" Q6 H6 l; e                }
' L2 g: @% F# d% k. U2 g
6 `7 D' m; G4 c: u5 x6 k                for (size_t jj = 0; jj < vec2.size(); jj++)
: t" ?* Y  \, Y  `                {
. A! b( B3 h+ a/ C                        b2[jj] = vec2[jj];- K8 p. A& v3 R' _/ h+ E1 H2 N( C
                }, a( y- W! L& E4 J, c# G3 N" c
# ?/ M2 v. f6 f+ m, q4 [
                //Method - 1  N=100000 247s  8 d/ k8 E; V" R3 G) W# z% A7 y
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);" W4 G4 D9 Q* w1 R( ^
                                5 u( J0 W! b8 N8 Q: X  l
                //Method - 2  N=100000  237s
9 d% f; i0 [  O+ S                /*! r  j2 B1 x% m: J& h
                for (int jj = 0; jj < N ; jj++)
) X0 l" ?: e/ ?                {
9 k& n/ Y6 H5 ^6 b/ ?+ [% r4 k                        fresult += vec1[jj] * vec2[jj];
, D# b5 _" z, h+ M" e3 P                }
' k( Q2 U5 I5 M4 a! H0 g. q/ r                */
: Z7 K" J8 Q9 k% z+ F% }                                
2 s, \7 y1 L+ Y+ D8 ^* T5 j                //Method - 3  N=100000 204s
$ {' q7 F# i7 |) ?                /*9 W  s; v) ?& m( `
                for (int jj = 0; jj < N; jj++)
3 v: }) G) s9 e$ l                {) q* d. Y; P0 b" m5 _0 N5 S. v
                        fresult += b1[jj] * b2[jj];8 ?" @& B' M! Y( F/ D* T$ y$ v
                }
5 ~7 p3 }6 z' ^+ Y' e7 f                */
: B+ S( b8 R* U1 x/ Z+ W, L
, g& B' }( \0 ]( ]+ r# |+ O                //Method - 4   202s
; e/ V# ~) p8 I                /*
& r5 x0 K' t0 ^% B                for (int jj = 0; jj < N; jj++): `: K5 p& Y. M) `4 C; o) D
                {. w* M* X  l& C, P% e. P: r
                        , g* s5 g. @2 G% ?' }
                }
) Y4 a/ m6 o9 z                */
( `9 y3 @$ P; F! Z: o( }                //comment out all methods, N=100000  202s               
- S; K% J, K! a2 k& T        }
1 W# ?5 x! _0 r+ P2 S9 ?1 `
" v- g9 e& J1 z4 {2 R' \2 S        delete []b1;
* N6 l: H( ~% }6 @" E        delete []b2;
' v7 q9 T& \, W; R. k* W

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
" {$ b- g4 W4 \) e4 L" r( y1 @
! O" e. y% p: L6 p' q你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?" D6 r8 g8 L' k2 j3 [$ G

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
% P/ M0 `7 M: A" p瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?* `% L8 {' o: |! P' d) J6 j7 w
! I. t" a% [4 W) L1 Z; }
你第二个试验里面的j在循环里面又重新定义 ...
9 T8 {* ~, l  K6 Z- @4 W, W. `
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
1 N  i7 _6 K2 n, a  |5 u
& h' {, E# i3 K  R4 e. L不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
1 N: g* E% _5 ]% I3 m. {9 b内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
3 W) m4 ^: U( V1 d5 H  f0 o+ X2 Q* y8 L: \# j& w, M& B0 K) y
不和它 ...
9 b0 A2 t5 B4 i4 {; S

' o4 L! Y& U* \0 P: S- R5 a* g不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。0 t/ k2 y9 s7 E( X0 ]# S
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54. _. e. O* y# S6 a5 C+ I
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 h2 g6 \0 S+ x: y{- ^7 Q9 M/ J4 j8 H& @  u
        comp temp, xtimesy;
) B0 L$ g' H9 T
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
1 H! H# _5 H. Z' w3 H- U内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
! s5 c, A; [8 t% ~; h) lVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
0 x) ~) F  R1 A. M& F- J8 T+ l! m理了理思路,重新做了一个测试。
5 \$ m; ^, F# Y7 a9 k8 ?6 u2 q做了两个 vector 和 两个 float *, 都长 100000
% @2 c8 A# \* F; K外循环 6000,里面先做随 ...

  w$ E. ]$ g! c" K! [" u1 w这个时间是从哪里开始算的?
0 p" B& C; J4 @" n, |我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
( j& X: X4 U9 `7 {0 H0 I" x. T8 R3 j+ y按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
1 J( z: @5 j+ p9 N9 Y3 W这个时间是从哪里开始算的?
1 n: D9 R. ]4 T我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
9 n: m' |5 \% g( N7 d1 P
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。" l$ [8 U4 W; S9 m7 G/ C" |, ^( ^" _
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。3 t3 K8 _/ i  u) a3 L0 K$ `
与此对应用数组(指针)花了2S
; |5 y9 D0 D" ]' P你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
. P7 W2 H9 e& g* Y# p* m1 f, P5 dvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) l! y9 W& Q- W{
5 Y+ C6 f! Z$ C  J$ U0 R        comp temp, xtimesy;
, J  _( H  k8 z' U1 s9 p
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗4 E- a; U9 [  z" f
9 S, O- l8 J6 S& B

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
! j4 @. Z; Q9 v( t$ f6 P# t/ ~我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
$ s9 A8 Q- U' N+ }3 ^" x7 m# w, h" c. z2 R2 K
...
& c1 n4 ^/ |6 Q5 w) H: [
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。" D- i1 r+ V# R4 ?& H6 L* G( O# E! d7 h

4 n" @5 W. v9 h( n  B0 ?雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
1 W# W8 N5 P8 U& N1 p
7 V& m/ `& u+ h! w* O3 E- j6 \( s是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。) C" S" m5 o6 h9 l
有空时我会试试 SIMD和并行,看看能提高多少。
- W5 @9 s% f4 K  F8 f4 j9 ^* {过去7、8 年没有正经用C++ 写过东西,没有 sense 了 3 U" h7 [$ h1 D7 c
谢谢大家的讨论,I learded a lot.  红包已发  
0 ^* ]5 b: M' _, J$ {4 f* X( k( [

' ]: J% ~/ h6 B5 A: ]8 ^- C
1 w5 N' x* e$ O7 N1 B+ A( i5 W
) h+ B) [& z7 W# l4 M




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