爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
) M: v1 P, h6 [# P& G9 ^4 f5 U( I9 m6 h( L. y/ I- H
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。9 E! [& D  ]% `8 W4 O7 r

! z+ o, Z5 Z3 ~: C# K' D# Z速度优化问题真的很有意思啊。
" u  r7 F# n: s) g  M: M+ {3 [3 [8 ]) y; E+ j
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
" ?8 {' V+ V/ y) |/ }  |" F把代码贴上来看看?  _; q! }- ?0 d% z

) L6 h8 F+ f2 F4 `3 K难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
( Q0 w8 n* \: S
数值分析 发表于 2022-9-24 23:04
- ?; w# C( \& p& D& ]拉下来?拉多少?
" ?5 n& J: o8 d7 ?; D! o! R把代码贴上来看看?

  Y' d- H; m; o/ ~0 u
: Q0 U0 r5 N' `9 u/ Cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) ]5 a: M% D6 z. P{- F( f$ `( ?: O" p5 z
        comp temp, xtimesy;
' \7 g- |, B, T5 X) `8 m        xtimesy.re = 0;" Z+ A8 s0 x+ V" M& U5 y- Y
        xtimesy.im = 0;
6 e' n6 |$ o0 i* w& L& B$ c+ q        int j0 = lenB - 1;9 y0 B& @+ G8 y& Z" H7 F
        int    i, j, i1, reali;  I; `/ Z& t* t6 Q
        if (lenA % 2 == 1)" u7 ~; i& [. x6 z
                reali = lenA + 1;
( [9 w0 l. f/ S, w        else9 B* l& ^! {5 B5 {
                reali = lenA;1 s- S& o) E/ }# F
        reali /= 2;
- U& `+ H5 j' I5 v6 g# h
; g( g+ T. S, z1 j7 A6 q' V        int nconv = reali + lenB;1 ?6 s( T6 F: @: o* L: ~. I
        //#pragma omp parallel for
5 |: p/ F1 U0 ^& c% V6 ~2 d        for (i = reali; i < nconv; i++)
" J4 R3 p2 G5 i) W5 s" V7 B' G        {
- O4 x; E; M/ ?7 A! S9 H& |                temp.re = 0;
: m3 {1 h" ?, y. j0 u  ]                temp.im = 0;
' t* {' i" ]) o7 o& o# ^                i1 = i;  P7 p% D, u4 F5 q
                for (j = j0; j >= 0; j--)
" [. b6 a* J# N( ^                {
6 _+ s7 V# G& C) {                        /* floating date operation */% D: H( u1 f4 ^5 R/ ]5 o7 U
                }

' M4 c- J# y% W/ h4 B+ U        }5 n4 h4 {7 P/ @* N, m, l. E
}
. w- @# p! N! v) ?( s) N* I, o- S. [- l9 E) e) v: Z6 A
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样7 E0 p' |6 M2 f! b0 `8 {) \
& n8 I4 _- C. Y  @' Z/ z* X
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。" F8 T. v- v7 o- X7 Z
现在call xcorr 100次,耗时78s.+ v$ _/ F) J& |5 F8 t" B
$ k" _6 B' ]0 e- @) L8 W# M
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. : w! ^8 g% U- Q4 V) y4 ~
2 G  @7 F4 {. a! i

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
' g3 i1 Y& f8 G7 i) s! wMaybe Debug mode?
2 H5 E" Y" |% Q
* N- Y& o8 \4 |4 V' I! o% a
不应该,看我上面的回复。
, z4 b5 Y$ r+ K% J: D8 b/ ~$ i$ r4 p8 l2 P% d
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 $ m5 r8 c2 P1 g2 h4 B$ r$ k
雷达 发表于 2022-9-24 23:54# D( z5 P+ [6 \; M! k) G
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)& J; Y5 N" S) \4 a
{( x- X1 o- l6 v' H
        comp temp, xtimesy;

5 t! f! B! [, g/ f: c0 R7 U* q# ~/ N5 t% m& r1 i6 W9 V
这个不是这么比的吧。。。
  o* W, Q, ~% P8 [5 H1 N
4 z% H1 ]9 o' Z) y您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
+ C, X6 |. v# Z+ d9 X" S" x4 ^: ?5 c5 ]2 P4 Z* ]& g5 s( I
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 2 _8 F0 @+ w7 e/ }
数值分析 发表于 2022-9-25 00:20' P8 a0 d7 I2 ~5 I/ L  S* k  b
这个不是这么比的吧。。。
9 P  O0 A* z7 v
; _5 R' `$ T5 A" l2 a7 n1 F0 N您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
7 B. Z: f5 {" A/ o
% J5 {$ ~0 o, A7 l' l
有道理。  g- l' k: s8 S" o1 e
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。; \- e/ @2 D! b, @

& R  S- F- k9 r& o我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
; O/ b) y7 \, }) }& q" R* ^$ X- u1 l有道理。
8 P1 i, ~4 \& r+ p& \$ o$ J9 V所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

, Q: Q! B3 c4 b" l你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
3 K/ |& Q# ]8 ]: q7 zWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
) n9 q# O, ]8 O' V  n' }/ v这个不是这么比的吧。。。7 N% Z, t6 h7 o+ o7 D* i% J

8 O5 p. b- g+ q2 D; E您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

3 G- I! I; k9 ~: R
4 m9 \# a% |/ _* i$ N现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 6 i5 i& f' {& K+ o% Z
沉宝 发表于 2022-9-25 01:48! S' [. u9 R0 ]8 p
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
' K; ~6 s3 D# f9 D1 R6 {6 e
/ g7 r/ s" y4 I0 O
是的,兄台说的对。
2 f6 O4 t2 w" F, N( ^4 l: j3 }8 a2 B; b- O+ T* R* F* Z
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
/ I! b" k$ h5 s  }7 H) _8 y; x- o
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
0 J4 \" `* {8 x
* I4 c6 U/ w& a# b9 U3 `比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。% d$ ?/ g/ n: B& O

  _" o, J! \1 l" b8 R! @7 @) `3 z当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 : M0 m: u/ V& o; H$ G
沉宝 发表于 2022-9-25 01:270 z8 |# w" X! J: u3 X9 e
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
; ?/ J# S7 [& D) K0 b' J
7 |( R, L+ |) l- k8 F+ f2 K- G$ e
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。+ q) H# Q6 f: Y5 r( m5 C. U

1 A  k) n% K* `: j( Q我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:472 S7 d" y; ?, ]7 H
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) @  z/ t1 x; u: J: [
时间差一倍的结果可以接受。
5 F% j! D! @+ Q% O/ [# d6 Z6 R( q) }
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
* S7 Z" H: g) G0 f
雷达 发表于 2022-9-25 04:476 k! E7 Z+ ^7 Y* G) u+ d
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
. {! H. t1 M8 K" z* b' y
, v+ v8 `8 O3 e6 A
+ i  s" C9 }' i9 U9 t  s

  ^& p, ^1 p* m, |  e能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
" i, V/ s& ^) D2 n: x
数值分析 发表于 2022-9-25 14:58; q- m( o) }: n  @- y
能不能把这个也贴上来,看看和上一个有什么不同?

; M7 x2 C* Q) p' G7 X. N理了理思路,重新做了一个测试。
: z& F2 |3 C  |' ^2 g4 h  c做了两个 vector 和 两个 float *, 都长 100000& Q/ ]' Z$ W- q* i2 x6 Z- u
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.' C, |* r3 t, D
' Z2 p8 m5 {/ P% i$ Z& A* @$ T" t
内循环试了4种方法,% m# J+ g* O+ M5 }5 I
1. 直接调用 vector inner_product 247s
! M) u# V$ E6 c( i  H: K" U* d0 X# i2. vector 循环点乘累加 237s
  [. B& h4 B+ u1 v3. float * 循环点乘累加 204s5 p* Q$ k  _0 B6 F+ W
4. 空循环 100000 次 202s
* x1 `4 T6 I9 |2 X
: K) D9 ]3 x2 R$ L- g/ j) w不做内循环 200s5 X6 U  M2 h2 g9 G! X! `$ o
/ c! X+ e5 O* a1 }3 M* ?
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
7 B5 i& x$ N  f6 [6 O% F- x' N3 a另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
" o' w2 M4 O! Z9 y. Z* r' H' g( a* {+ k, ~! J
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
6 T4 S2 u7 o+ }) A; ^" X$ v7 t9 U1 Z) g# o% T; N4 ]
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)1 [% v* u1 t3 j( l$ a

$ Z0 |/ [+ k6 i
        std::vector < float > vec1(N);
: @2 N1 p$ I$ q! J- F+ D2 X* p" F5 r( u        std::vector < float > vec2(N);; ^3 f  H+ h9 G" B' R
        float* b1 = new float[N];5 r  B+ i* `, f" D8 Y
        float* b2 = new float[N];$ }- o  Z8 ?& b
; a- f1 ^+ Z7 `: Z* R% f+ A
        for (int j = 0; j < 6000; j++), g8 B% _1 J7 a" t) n9 O
        {+ C4 X3 x* c& h
                std::generate(vec1.begin(), vec1.end(), []() {
4 O  T8 `) \0 y                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;& |, p3 M0 x2 o0 e
                        });
8 f# v. I, H/ |. @& ]5 x$ D7 Y2 i  P& N
& t0 ]! @# E6 O4 x  p' p$ W                std::generate(vec2.begin(), vec2.end(), []() {6 y) t0 w5 Y( k. @. K1 i  N- I( I$ X
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
9 W9 L' p- k6 c, p/ s                        });
' I0 M' s$ H4 r! S
' `% e! V3 k" d                for (size_t jj = 0; jj < vec1.size(); jj++)  x3 L. m+ s* x7 b2 O5 h
                {
3 Y. v9 _$ S+ c* l4 L                        b1[jj] = vec1[jj];  y4 a# Q6 E; Q
                }
2 H1 U7 q% l) I: [4 K' ~4 o5 H* e
& ]/ g7 M+ s2 `/ a2 c                for (size_t jj = 0; jj < vec2.size(); jj++)7 F! I7 N. m$ m! B8 Y
                {  G/ s  ^: }; R8 r; s& l1 i8 K* u
                        b2[jj] = vec2[jj];1 v4 P) }  }5 P2 L/ m6 A1 ?
                }
6 i( R* k  I3 `  R4 f
& P( _4 H, j; _: O2 u8 v: t- H$ c0 u                //Method - 1  N=100000 247s  : @9 E# u$ F. s: H1 y
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);, A% J3 R7 B/ E: l$ u6 H; z
                                : L; d& |, e5 m9 \* k
                //Method - 2  N=100000  237s9 W9 q  h* z  k4 L/ }: r) q, w
                /*
) Z8 R4 |* s" Y" b- c                for (int jj = 0; jj < N ; jj++)( G1 `" [; g" {! D
                {
: q. n5 H  _  y                        fresult += vec1[jj] * vec2[jj];1 m. o0 c; V: ?& j
                }
$ r" U$ l; ?0 s# a4 N                */
' S7 ], b; a' K) Q                                * L. v- D* ?/ h' ?6 L- `
                //Method - 3  N=100000 204s
5 j, @$ b2 H2 g* C                /*
2 w  a! V. K# v/ q  j                for (int jj = 0; jj < N; jj++)* y/ k$ Y5 q/ }
                {' Y( T& l7 {% y- v
                        fresult += b1[jj] * b2[jj];
3 \9 Y/ w! O8 [' o, p0 v. [                }$ H) Z6 ~; h$ J: ~5 O  D+ d+ T
                */
8 c8 F6 j7 P0 W+ K- R1 n, f
. g) O4 l9 N7 }) S3 ?6 Q) P                //Method - 4   202s
* i+ h- O6 ?6 S, [% N$ C1 z                /*1 D, M0 s9 F; s5 a5 i7 e, g/ j
                for (int jj = 0; jj < N; jj++), d  Y: y. u4 B* k+ T* K( R4 O0 p
                {
$ L" }" l) s/ _- I, I/ O* _' a& @                        # W5 \" C, D( X8 X- |  n3 R- X
                }
% }' [6 U/ S0 R4 C2 F7 X! R                */
$ w/ ]4 _! s# S, u3 _, L; ?. ]. e2 a                //comment out all methods, N=100000  202s               
- j4 P: d' {6 z: a6 ?        }6 j, ~* i, k# ~$ _, f9 R
% p" ?; d' e6 l# q
        delete []b1;. V& w; E2 O0 H( m' d
        delete []b2;
: g7 m' m5 p$ J! {

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?3 {. J: e$ w' w- s. J
+ s) R" O5 ?! q( w1 p( u
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
. p% w1 u& M" \6 V% {" J2 [8 E
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
: b( a# Y. A; p6 x7 H) J2 n9 s! T6 M1 }' B瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?0 K% }0 [3 g/ I( {* O% q# L

1 b8 a8 g# C' e' m7 C5 R( O2 M你第二个试验里面的j在循环里面又重新定义 ...

* Q( Y' D$ t2 d内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL# \+ {9 V- C; |. I3 f" k

+ {4 W3 [2 j3 R# b) Z) P, n不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:165 t' g+ S0 D. O
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
" ?" O. p: p2 t( {  o& H! L: _8 q4 c, h3 \: D6 s, g
不和它 ...

5 i8 U/ K# X; J4 x8 l: S! A1 [; Z
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。0 |5 Z) `$ N+ m% ?5 D: _0 P! a6 s8 e
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
- i! c+ M; y; Y! Y2 tvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)# K: f3 x8 d9 }' f3 m
{3 t8 C5 l5 J9 c4 j. m
        comp temp, xtimesy;

5 }+ v- B3 T2 C8 ~: a# G6 @这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
- \& z) v% p, `( H" ?+ j! a内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?' L; w% r0 O! K. W2 J- a* L
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
. u+ a! w. a' s/ X- E! }" d理了理思路,重新做了一个测试。4 Y  B$ @  N; r* w
做了两个 vector 和 两个 float *, 都长 100000' u! {0 j9 h2 `8 ~
外循环 6000,里面先做随 ...

7 m) C& }3 g, I& R! o; `: \. b* y这个时间是从哪里开始算的?8 }' s4 P7 Y6 j8 ]- Z# Z" }& P
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
. R2 @2 u8 j# `2 U' }& r+ o- {按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39$ y2 _6 v& V: B+ x
这个时间是从哪里开始算的?" O( y' _& v$ g" R( g
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
  Q& v* o$ @5 x; t6 W
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。1 z5 B: N1 S4 a, r5 K* L8 _6 E$ X& M
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
/ T4 ]% q* ?! u. B1 {- _3 f7 a* Q6 H与此对应用数组(指针)花了2S1 ~( m3 j2 M/ k4 E: ]
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54; I5 E" Y* X8 C. [. R
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
! e. ~: _% J8 k3 Y{
4 L) W, O* o+ c* P3 G4 b. T4 ~        comp temp, xtimesy;

. t- L1 r  _; s8 _# M* f; ?我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
$ ^$ v  {6 V9 e& r- {
. R- o( ~2 v# y9 E4 Y& P: ]
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:290 J9 b9 a' ?; ]
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
* ^3 `6 Q9 Q$ }4 h- `* z- N4 V( W! X
...
5 j' Z! H! p9 }5 L: A
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。7 [! \" s" {, W' T6 w0 i1 H
, q& g# V* I. w& n: ^
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
1 ?: [% k' Z4 q5 Z
8 ?6 L# M3 M6 `) N3 F是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。2 {- V( K+ M) j3 B" r
有空时我会试试 SIMD和并行,看看能提高多少。
% a% G" s( \( ?1 D1 b# K过去7、8 年没有正经用C++ 写过东西,没有 sense 了   R9 _5 C7 c/ {6 t5 I. ^$ K( S. h* r. N
谢谢大家的讨论,I learded a lot.  红包已发  ; ?2 e5 I# g4 c+ Q/ X- Y+ x

4 p; M- z5 a  L2 n( u# C% g% a9 N  ~, Y5 [2 Q3 L
4 I0 H4 W- I4 b# {% `# T( j
# {4 p  Z# m; F/ t  y4 }





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