爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?. ?# P0 y" K- n$ f4 v
8 T7 T6 V1 I( C1 _
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
' k3 e! p* w, e8 z' u
& w+ m0 u% m5 b+ P5 l, F- J! n速度优化问题真的很有意思啊。
$ G# [6 Q9 p$ O$ D. i4 `1 t0 g, X2 z. A6 U; M
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
" x; R0 N. l2 o; n把代码贴上来看看?+ I" [- _* b( L

# p: e5 p, a) m  w+ U" l难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
" J  ~: M0 x( D( H" |) ]. B4 w& y
数值分析 发表于 2022-9-24 23:04+ }6 O. x" w1 p! I$ T: [, A
拉下来?拉多少?
" B9 L/ z- G. S* `( _) ]/ b6 F# l把代码贴上来看看?
4 n8 ]5 l0 _  Q1 A' ^- C

5 b4 G3 t) l; B1 f0 W2 I' ?void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# U' C. v0 r4 W" g: q6 i* e{, e1 J2 Z) Y: E5 S. M0 w
        comp temp, xtimesy;
. }: ^( x" W7 E% S  M% Z, N1 K        xtimesy.re = 0;
. g0 F. d5 x! t3 Z0 w' s0 ~7 i        xtimesy.im = 0;' w6 c# E9 e$ K; z6 }% u
        int j0 = lenB - 1;9 P% F8 b2 t# D
        int    i, j, i1, reali;
+ d7 C# s: o& W: x+ b        if (lenA % 2 == 1)
" X6 ]% C6 c- w- T/ \7 L, I- _, d                reali = lenA + 1;
$ N% I' [# M" F        else
) ?* f( v' R9 Y8 j* ^                reali = lenA;
+ l9 u2 @9 o2 _* O9 f        reali /= 2;: C+ K; \3 s4 I! A- h, a" E
; w. A' h  K) A' x8 v- T+ x) A
        int nconv = reali + lenB;
3 q# J7 F& o' h; s        //#pragma omp parallel for
9 x- e1 L" o0 i0 c# @0 F! W$ t        for (i = reali; i < nconv; i++); M4 z3 X/ G7 L; n+ e6 Y
        {
# Q2 I: l' ^6 w0 C# s1 |8 h- d                temp.re = 0;
2 Y9 k6 P' }3 Y2 N0 _+ [! w                temp.im = 0;
( D7 s, W. M- r1 F# _3 I( b8 y                i1 = i;' H- V. C6 \6 q( B" Y+ k$ Q
                for (j = j0; j >= 0; j--)
* e6 ?$ M5 J, n                {. I6 Y8 q% S" j; P
                        /* floating date operation */" L+ p9 ^. i7 R) _
                }

" [6 x8 V0 o( D. B, }( j1 L        }: w4 x) }; P! a, A  p2 o. o
}
+ E( e0 ?) Z) h# y8 {
( O; u$ F) \$ U" V5 W- \xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样/ p0 V' g' k- U- c0 v; l

! a' C+ L' r' {& j) X% I3 [红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
' P/ e! l* f9 J# x% `" D' z+ a现在call xcorr 100次,耗时78s.
+ S  t2 G% ]& c. T" J2 @  ]
  q% F- T1 B1 S6 V) t; p如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
- D+ Q5 m  M8 n) C7 {) U" K3 O! W8 a! p

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33( e' c- J) {& Y& w. r1 n
Maybe Debug mode?

- \) m2 d% x% k. _- D0 l$ D. f; I6 m
不应该,看我上面的回复。; t- a. c* ?  p( v

5 @- o# }, L' T我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
+ o; R; V2 p& g* ]- q1 N
雷达 发表于 2022-9-24 23:54
! M0 t3 K5 P( @1 ~' _5 _5 svoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' s2 [* V( N4 m# \{1 O& i; F0 d% G6 s, q5 O' b& b6 }
        comp temp, xtimesy;
1 G6 _  E& n# F$ D7 R, b, T

; B' B( v1 f# N! s, K% Y% z这个不是这么比的吧。。。2 h5 \6 J0 J: A8 r! M
# d$ i% ~! r7 [3 O% S% f, a1 |
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。3 c2 j) M! x# r9 p& N: x* Y

) B7 u. p+ F  v" g而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 1 [' ~. K4 I! j. Z4 B
数值分析 发表于 2022-9-25 00:20
* N# }+ i- c  C' Y! n这个不是这么比的吧。。。; \  M/ d# B$ i3 h
- B* h( h( y% L4 Y
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

3 S8 x' u" j+ v1 V' \
. g2 _3 m9 n" r9 }" s有道理。
7 l* I+ t6 F. f+ T: |- A' g1 K9 E所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
4 \/ h) E7 n3 e# H4 q5 S" T9 G! O+ m
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:463 W; O3 k9 t3 v4 ]* U! g/ O' S
有道理。
; G( K- y; R$ W4 Q- X/ f; \$ s所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
  U* I; n; t: T) b% R
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多& d4 u& e6 g8 [5 C: W
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
2 o; B, y) i4 r2 I: ^: c, |这个不是这么比的吧。。。
$ B. X! Z4 N" X$ r$ T6 e/ |+ @' Y+ V* l9 P6 ?& r, |
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

! t) m: U% H! ~. x# b% {1 w9 G" i. Q
0 P5 e5 b) O1 P- I9 ]  `) }/ F现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
  Z8 [8 `) A. ~1 j( S4 Q9 u& D
沉宝 发表于 2022-9-25 01:48/ a% n+ Y/ z5 J/ e7 i3 v3 F+ Q* u+ t2 `; \
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
$ V' H5 X; S9 n% T4 a8 ^
. {- T( ^/ f) E  Q, P  U/ `6 H/ r
是的,兄台说的对。
( T5 l% q6 F8 j  ^+ |
( s* @6 v7 k& s6 _  n" r其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。0 I* B* P8 u" \/ i8 m

9 q, q; I& R+ t- h+ B6 J5 {$ ~雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
  g# N! E& S- b1 v" ^; V
2 @2 N+ c& w$ \) |8 ]5 F0 p! \. `比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。( r) W# V& X" `
$ H8 |' ?5 G; v# X/ a# }. r, t
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
% X- K6 m1 |$ K5 W% B0 m
沉宝 发表于 2022-9-25 01:27
! B- K# C( y' Y你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
* B/ c* ?7 A8 U; B3 D8 q
$ n: G# j! g8 f" R4 ^9 M# u4 J- @
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。# }! g6 A! U6 y7 K0 S8 B0 Y

5 U  R7 Z( G: H  U5 p9 [我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
8 C$ Y- N/ ~5 b9 G又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

9 I1 l+ Q( q: y" c+ p! Q6 a时间差一倍的结果可以接受。
# F1 L& |  z: D/ N2 ]! o' h; J. ~
8 f' L3 E* o0 ^& O+ _5 O/ U! f你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 % K4 J7 I* |2 w8 T# u' G
雷达 发表于 2022-9-25 04:478 z  M5 h% q: T% f) h4 M: o+ D* k
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

8 Z" T; i+ {' |2 G; k1 f" P: q2 k: I) H! W; V1 _
' A2 s* ^# r8 |2 D4 N

% s- _' Q7 Y- {( C& r能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑   d% k& K2 l) m* h1 }* w
数值分析 发表于 2022-9-25 14:580 E8 M" c! `/ ?$ f3 F2 S- ~
能不能把这个也贴上来,看看和上一个有什么不同?

" ~7 r: Q, P& u! ?# b理了理思路,重新做了一个测试。9 ]* G6 X1 O: \, V2 J( n
做了两个 vector 和 两个 float *, 都长 100000
1 ?8 y3 H% ^+ d# U4 h外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.1 x0 {) n1 I: ~) H+ \+ ]

0 U. W$ D2 p3 f8 `# @内循环试了4种方法,2 Y  r, d; N8 |4 I
1. 直接调用 vector inner_product 247s 1 z0 W8 g6 w1 M" I5 o, K3 p: ]
2. vector 循环点乘累加 237s
5 I- _9 p4 h3 W* P; r1 q3. float * 循环点乘累加 204s
2 |0 g- m9 K; U: C  i6 X" L( ~- P; r- ~4. 空循环 100000 次 202s- M: x: u& W& C; i* U9 F+ f+ m$ u

2 t: A, q) b5 r不做内循环 200s% K) z3 S4 S& p0 {- T! L
2 o% t9 l- T" p2 I1 {- v) A
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
: X6 i: f' k5 d3 g) v另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
1 M8 H& V6 }. e& z' B( b4 z5 B5 s2 M/ h0 p+ V2 [+ q
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
: W+ ]' H/ ~4 F; A2 _4 \3 F0 w* \+ g
6 e) y' c2 H; Y(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
8 ?* v. f+ h) H2 W6 i. ?" p: u* }$ W3 e& Q* d/ ?2 }
        std::vector < float > vec1(N);5 u* s( |1 d2 @' z5 ^0 L5 x0 i
        std::vector < float > vec2(N);+ q) Y4 Y( I) }& W  }1 ?' P
        float* b1 = new float[N];
8 O# H. T8 {" E  A        float* b2 = new float[N];5 x, q- t$ V' S# K
7 l& J4 ^3 w# {, {8 B' F' P9 k4 f
        for (int j = 0; j < 6000; j++): h* O! M. E5 ~; V& O% \) I
        {- ]* n& Z+ M( `- e) V4 k
                std::generate(vec1.begin(), vec1.end(), []() {
# J8 M1 |. W5 t' Q                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;, j" C9 q- c% j! L  Y: ], a+ K% d
                        });
* Q0 d7 h3 M  s' x! ?) T5 C6 J- _0 A/ k8 x* G% |
                std::generate(vec2.begin(), vec2.end(), []() {
" {$ P' g. v3 f9 e6 z6 {2 T                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;5 P! W: D: B, E2 N& [
                        });
+ s, ^; k* @& a! i9 B3 d2 @: d: ^0 p" V# N& @: v4 L$ P4 Z
                for (size_t jj = 0; jj < vec1.size(); jj++)' |& `) y. h" l* ^3 W& I
                {
4 R) ]+ n% Z3 o- v$ E# T                        b1[jj] = vec1[jj];6 e- r9 E* w* q: D
                }
  @. H4 w0 b7 ]- F  b4 c# e$ z/ e( K4 `6 w" e2 T' x5 j9 w! ~
                for (size_t jj = 0; jj < vec2.size(); jj++)
0 z! g" D% H1 Y1 ~% T                {
# Q+ O0 f3 e5 d2 G1 J4 C                        b2[jj] = vec2[jj];
* b( R6 N" v$ Z, ~- O                }. f5 Q- a) v. K; J, }+ y: S

9 M% I* N7 |1 q                //Method - 1  N=100000 247s  + z0 r# h$ x- O0 C$ U8 F! e
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);. G+ L9 V' g. ?! w
                                ( P6 W( U7 l4 w* n( n
                //Method - 2  N=100000  237s
1 `; ^0 c6 B) W( s0 C; P                /*
# W4 |! A5 _, c8 K* o# L                for (int jj = 0; jj < N ; jj++)
3 \# y2 _  ~9 E! r/ Z2 e  }# C                {
; }4 A3 m( G2 |                        fresult += vec1[jj] * vec2[jj];' m% Z# Q$ T& y. q! }% S3 h
                }
$ H+ S( H+ q5 ]) [) M! ~9 _                */
' U- A1 e' n3 ^4 m5 Y8 a4 `                                * |( t7 v* c( B
                //Method - 3  N=100000 204s
2 m+ S( ?% e" K) K" C4 v. V                /*
0 X. ]/ N5 ~% D5 O8 N                for (int jj = 0; jj < N; jj++)
; N, B. r& ^0 f( H9 i                {5 o" H; a6 \  h) D- \  W
                        fresult += b1[jj] * b2[jj];
3 A4 W; X1 E: W# d& c                }
8 H* ~4 u0 i: e# u; {                */7 X0 V7 W# d+ v- N' O: K6 p* {! s

, w, m8 r0 C. b# J" C- E                //Method - 4   202s" W, k, @& w% s$ {9 t: I
                /*
" i5 G. y# ^5 I" l1 z                for (int jj = 0; jj < N; jj++)
2 R4 v4 j  K& z, c( X                {
; B( z3 A* h) a" j' b8 m; N                        
2 ]$ J5 ^: `" o! f                }
3 m8 Q: y; l$ p1 X8 n                */1 s% t( j2 Y3 G) H
                //comment out all methods, N=100000  202s                ( b# Z5 h9 r  O- O
        }8 ]5 Z* i, f1 Y5 _. b
3 m9 F' A1 s/ `2 W
        delete []b1;
3 F9 c$ d4 V3 u# Q        delete []b2;
) G7 v3 N1 [  `4 L) d1 \

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?. v* q5 M+ o! f/ s$ M8 o
$ q9 ]$ v/ Z, Y  B! K: }& E
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
8 Y" F. w; m- v) c" j, I  ~
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:150 y- _2 c! b8 m6 T% n( l
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?3 J3 Q* W. t- M

; H3 ?' ~7 O$ ~6 D' y你第二个试验里面的j在循环里面又重新定义 ...

2 D5 f) ?7 H+ W% |内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
# q6 R$ b1 [6 S; q& x! G
, \8 X- @6 L. f. o+ c* N- b  R3 q不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16( @5 Z7 `9 w6 M8 s
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL( k7 f7 f1 v2 _5 y# J; ?
  g, }* `% C9 z6 G* J" d) z1 o
不和它 ...

/ I1 F/ B, Z$ h' u" d# R; V6 N* d8 b- |: H; p4 ~
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。4 x& n4 ?: R, \4 V+ y' J
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
; Y! ]" c% V8 T/ W# r& h/ ^void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( o; g4 b- D/ r& a{. Q8 S7 h# U. T* k. S  c
        comp temp, xtimesy;

: s! G# j8 G$ B/ y! n+ r这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
# ?! ~9 P$ D0 Z6 Z( c/ O* s内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?3 y! p1 r! r  c$ W) c. Z
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30' ]1 }8 R% S: w: ~) r/ M/ n
理了理思路,重新做了一个测试。
) ^9 ^" [0 e# ~3 e5 U做了两个 vector 和 两个 float *, 都长 100000$ j; o9 M' C4 B% u( F
外循环 6000,里面先做随 ...

8 L: c4 H7 z3 ]$ D" l/ c这个时间是从哪里开始算的?
) ~: @! g3 |9 Q我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
+ p3 D: n  L% D! `0 x! Y" f/ w4 U9 K按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39( i  Y0 x3 F: E
这个时间是从哪里开始算的?
; N0 A; K. V4 K* {4 m2 n( s1 q我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

' d( n$ t* c; A  x我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。  J6 q4 f+ S9 A( l/ e
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。: ?6 A+ t0 M4 a* a9 h
与此对应用数组(指针)花了2S! D7 `$ M8 C8 v1 g
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54/ X: _" t& [' ~1 _
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) j0 |# C: @8 ^; W- p+ ~- m+ e- G
{8 N6 G/ ]8 Z( p: k, ~
        comp temp, xtimesy;

: |* N# ^% V" @/ M9 L2 r4 o% p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
) m  ^9 O7 W8 D! V( x6 ]" a5 Z* h9 Z

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29' ~" f! P3 W/ V7 x. v( X7 u' e
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
4 Y, @: `5 U4 h# H1 R1 `$ S1 O- `. m0 V! l
...
! V% B4 I  v5 C9 y
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。& N( b2 u; ]1 \* Z& g. y
+ k7 h4 |( p! t' H9 i, W
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
" p0 D7 Q; B% n, L( b1 M7 m3 f. Q9 m3 x8 b8 B- Y- z
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。4 k$ {1 B/ F" s$ q( j9 f' h
有空时我会试试 SIMD和并行,看看能提高多少。
/ P* p9 m+ k# v+ [: `7 O2 H% f+ X: Y过去7、8 年没有正经用C++ 写过东西,没有 sense 了 + m2 N- v! f4 R/ C3 M
谢谢大家的讨论,I learded a lot.  红包已发  1 f% I8 k' i; m  Z* S# Z
. M9 y& d2 R! t. I- C" U. L; K- @# U
% n8 t% b& ?0 V. o* B( F6 K: I( ~

: ^% T- T9 W( D, l- m, d2 Z6 Q
8 @  Z/ a4 i1 u7 Y/ ]+ L




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