爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
% L3 i% M  ]7 u% Q7 f: A0 a+ M3 \+ x* p* H2 s* k8 r, R
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
4 {/ ?$ E1 z& O2 U8 m
3 Y! i7 r- B5 {0 M0 L速度优化问题真的很有意思啊。5 V: |) s4 s, q
) s3 w4 J; X0 }6 _
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
# C, n; o& a: |$ }" ^' q9 K把代码贴上来看看?
: N( A/ r5 V, R! I: F  T" j/ d8 F% Y% Q
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 * c/ m6 u! [8 i) m2 K) @
数值分析 发表于 2022-9-24 23:04: A9 d+ T1 n' u7 X7 W. Y( n" J
拉下来?拉多少?
! E, k- ^* a- d& N' y把代码贴上来看看?

! k9 Q* h- p' c1 x9 h) E" `/ H7 @3 n# T  p8 {
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( I. |* q5 l6 b+ e# }6 j
{
" W8 f0 _. \6 }* [' {% `        comp temp, xtimesy;
1 X3 ]- e. c& ]6 e' M        xtimesy.re = 0;, c. {: Z/ q& y& y( w0 n3 ?
        xtimesy.im = 0;1 {# [6 B; Q' r/ G/ r( }) T9 S7 n
        int j0 = lenB - 1;# [  z  o4 P/ L1 D- t- g8 _
        int    i, j, i1, reali;
" d) V; W" w5 W) t: K) C, x1 M        if (lenA % 2 == 1)  j) [' n4 W( o) @! Q% ~  e. b
                reali = lenA + 1;; }: Y! K  e( I
        else
$ C' c+ i6 w7 Z% i6 z% N                reali = lenA;7 a5 |! h/ U2 b! B$ e' K7 V
        reali /= 2;& F& ]5 K: ^: b2 D& ^# @& j! L

0 y0 t$ {: O+ o, I$ K1 F        int nconv = reali + lenB;
7 u! s  X0 o4 z- j3 B6 W3 k. F' W4 M        //#pragma omp parallel for
: ~2 d7 K5 r' z. d        for (i = reali; i < nconv; i++)' h+ F" `' y1 x- s, e1 [' j9 H
        {: E/ b( l& u  P$ V! I1 q
                temp.re = 0;, I7 E+ u% z2 e  \+ E; f
                temp.im = 0;3 v7 n: C5 x* L9 `( I7 [: E
                i1 = i;) S0 y: w4 d1 b7 a7 v
                for (j = j0; j >= 0; j--)) b7 ^) f1 Y- L9 B1 t
                {  v2 Z5 ^3 q0 B% B
                        /* floating date operation */' b% u+ K, U4 P) E
                }

/ V$ f3 C" P6 T* ?  [        }$ q6 J$ V4 _# j5 x1 y! J3 g. n5 }! c
}
9 J9 H5 l7 K% D0 p
3 k9 V1 Z) ^7 L% C" B0 Hxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
- K/ m+ [& E+ I. M3 |0 L- T% b
# R& X: }, N" u红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。2 g3 S  j3 I* C, u2 E
现在call xcorr 100次,耗时78s.
8 Y! E+ B/ r1 p3 y5 X* ?/ c, J+ L6 P9 y  T. X) Y
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 2 I, F# m3 o- r& c% q1 R& L5 r
& c; F, A8 q, C$ {5 l& N

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
$ i$ F( s- b. \- ~Maybe Debug mode?

- ~# ?, G2 ~' |: u2 \  f3 t) U" s4 d# b' n- f
不应该,看我上面的回复。
7 j: ~( G0 K! R/ k0 B9 C6 V# e
  y% B6 t* F2 t/ ?4 t, O  ]我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 2 _' M: M& _3 k, O$ Z  W
雷达 发表于 2022-9-24 23:540 m. U% |6 G. L7 j/ f1 e3 o! J6 g
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)- [5 M5 h+ O( J' x' \4 K2 b9 P
{
# r0 p4 W( K+ B1 ~& C8 U        comp temp, xtimesy;
$ @4 ]& y4 j6 [1 J

" b; e( X* |9 a! `/ C这个不是这么比的吧。。。
' n) X) J5 x7 P2 R4 W! a% }+ _* P: h$ c6 r
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。2 j0 Q3 B+ U. z9 @$ S. M. F( V1 M
' f; C: \; T: [# ?
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑   ?3 d# C8 ~$ {) H8 E' N
数值分析 发表于 2022-9-25 00:20
, `2 A$ n: e2 F& t3 O这个不是这么比的吧。。。
( e" p5 S& ?+ u( f! k: q
. e& R& h. v" C* ~' v1 a9 |/ |您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
6 v/ Q# T( j/ ]- S
' y. e+ U* s; q% j6 u& U9 D
有道理。
1 m0 i# w3 Q( {: G7 k7 y所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。. ^+ h+ Z9 s1 q4 j! d

/ z2 W4 T, w9 }/ s* ~+ T我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:467 ?4 C. T8 r$ g9 t7 U4 G
有道理。: O. G  ~; U% c' ~5 E" B! I
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
4 s; @5 a0 p1 S! Y/ p
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多$ Q9 F# n& i6 D. |" Y5 v6 p. J
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:206 k- S3 _- e8 J& _; q- v
这个不是这么比的吧。。。" b* w6 ~% B7 Q& C4 H  W/ {+ W; R

8 N7 U# J# L6 T. x% h$ f3 e您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
( O" v, @+ {# w' h2 I+ E1 d5 S+ `
* f1 \  ^: p7 E( ~1 y# G, t
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
6 V5 i( [) q: j; ]; e, J
沉宝 发表于 2022-9-25 01:48
8 w' C' K5 t& }% S现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
0 X  Z  J+ U5 E2 N/ q  m' O: i, W1 E
( C2 L/ q" N4 ~7 w* M8 ^
是的,兄台说的对。; I3 c% J' z& P; g
( I" ^0 P8 T; i2 x6 P& P/ B
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
  _) Y' ?/ X' u' c- c) p$ J& o5 e. a" D; b9 j
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。( g9 k  Q# n0 l6 R6 @6 c/ r- f- k

' u4 q5 A. @! A. i6 N5 s比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。, O6 B/ Z  K# s# p; n& ]2 J/ b
3 |. c7 A" Y$ I+ q
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 . o" V# T3 q! J
沉宝 发表于 2022-9-25 01:27
- ^# z' q0 `8 X你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
, G5 B1 ^) L( |) |2 Z* F! K. ?
1 F7 g- s8 Q4 z% Y/ j6 E
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。: Y% m2 \3 N" J9 B! l8 t/ c  [

0 R* d* Q; a% J- G我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47* V+ H& E0 J' S( F* v! T% {
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 w; T3 d/ o* o* V: R$ v0 N
时间差一倍的结果可以接受。3 m3 i  C' Z, Y
- T9 {2 O6 g' |# X" ], c
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 - l7 W9 C& i0 P; v5 A$ Z! @
雷达 发表于 2022-9-25 04:47, F& a' `- X, \1 h' c- z8 R
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

1 O5 E# E+ j5 q; f2 O2 \: ?# ^
8 z/ H: f# R4 ^; }4 a) C& \- I' |! q' D' {! G8 C& i/ U3 E

- b+ T) c1 q; p4 ]5 L能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ( I6 T# e. k1 q8 ?3 ^! h: Q$ f2 T
数值分析 发表于 2022-9-25 14:58
( m$ I: X; Y7 |9 g9 v能不能把这个也贴上来,看看和上一个有什么不同?
  k; K& |! Z6 g( E& ^: ]8 w: `
理了理思路,重新做了一个测试。
! U# n. P1 [1 I+ Q/ ^做了两个 vector 和 两个 float *, 都长 100000. S7 _) G% ?5 w; p
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.& X5 e0 q+ c- S; G0 h9 M
( E4 D' o- W8 @" }. Z; [# S
内循环试了4种方法,# y- t# ], x7 F
1. 直接调用 vector inner_product 247s
1 A  ~/ P' X3 J( _5 L" w$ \& o- F2. vector 循环点乘累加 237s
5 `0 k8 ?) M5 B' \  d: s3. float * 循环点乘累加 204s
: a- P, X, `. N" J5 a4. 空循环 100000 次 202s
: d  a: T: v- C% m5 R2 u$ w9 B. X3 k1 a' v
不做内循环 200s* w/ u2 H2 t- D& e

0 D! ~$ L' O9 N) ^# G- E4 o你昨天说的对,内循环本身占比是很小的,大头在其他处理。
9 P: {# I. u4 s" @* U另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
+ S1 Q3 Q5 N& Y& m9 Q$ [6 k$ x" q- |
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试), x' W( S  v' E  i

( j- V& g! m, U+ b, Q(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
, K# n' C) P" z! T5 s1 T1 M* ^. B/ L+ Y4 v3 ~
        std::vector < float > vec1(N);- B4 O3 [) P% W3 s  N( }( _% ^5 o4 c
        std::vector < float > vec2(N);5 L* B  E+ d5 D! ^5 x* s# n: e/ X
        float* b1 = new float[N];7 R( M1 ]9 H+ ^( \4 \
        float* b2 = new float[N];
% t; Y; N$ X" y( K3 ?/ ~- A/ [" [# \  ?5 ]
        for (int j = 0; j < 6000; j++)% ?+ N) E. M4 }7 d; G, |1 n, Y
        {
2 i, m, n8 N! ?2 v/ {                std::generate(vec1.begin(), vec1.end(), []() {
" s4 X+ U0 M) [2 o% |                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;" l/ n- M! J0 i" |1 ]
                        });
- y( Q: P# L" J9 v  K
4 W1 o- V; F4 r% R                std::generate(vec2.begin(), vec2.end(), []() {
9 x' M6 I: E1 M0 x- h                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;# ~; N9 ?5 j! V2 @5 }4 t% H
                        });
% d3 L' w* m) f9 o- d+ S5 E
' `- e! c) c5 ~! N$ B. Z                for (size_t jj = 0; jj < vec1.size(); jj++)1 E# j' E+ r4 U3 O7 I
                {5 ]0 M: }! ^! _8 F1 B+ n+ u
                        b1[jj] = vec1[jj];
5 o- o' Y% |( ?5 D6 N* D                }# [) `2 m7 h' ^/ O; B
# m* t7 Y' `- a' O/ B: O) R* \" L( d% V
                for (size_t jj = 0; jj < vec2.size(); jj++)
4 I, m( f3 @& y0 o) S                {
  d0 ^$ ?$ B) s$ ]( O6 h                        b2[jj] = vec2[jj];
' ~: ]5 H% ~" {& m                }4 N6 R7 Q- ~6 x% g# v" ~1 L

& z. Y8 I# |5 M' p0 s                //Method - 1  N=100000 247s  6 _7 z  {6 g" |& k8 O7 C- m, K
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
9 r6 A- r7 @) L                                
9 Q, H: e0 P$ P: S# A; {* ?                //Method - 2  N=100000  237s3 b' o1 [. c# b7 K  p
                /*
* h3 `" c$ h+ Q                for (int jj = 0; jj < N ; jj++). B" E3 E% r  I" Y8 p5 `. e7 u9 H
                {
9 N1 J! H" q3 k                        fresult += vec1[jj] * vec2[jj];+ b3 I: I$ c, d4 r( T. Z
                }( `7 T; Q, F* {5 E5 q+ k
                */
4 `; @- }6 o& D$ u' m& ?0 {0 i  @                                8 L9 `7 U7 ?5 M) x, p  m
                //Method - 3  N=100000 204s
: I3 X$ I. |6 R  B                /*6 ~5 _' S5 f$ R% x' ~% \. g: Q
                for (int jj = 0; jj < N; jj++)
" D+ S) Q+ T2 D" j; Q8 I                {
# I: N/ }8 ^! h: R) b" u                        fresult += b1[jj] * b2[jj];6 V  I0 O+ a& N5 t7 N! h
                }
0 Z# e$ S* |+ u; [: X: b& ?0 S9 p8 s                */
& n) m' _, u$ f. D
$ s, V9 H2 C/ Q1 S% X; p                //Method - 4   202s
1 P/ c% \9 u+ m) `6 N                /*
  O7 l. Y1 \/ S9 s/ O9 E) h                for (int jj = 0; jj < N; jj++)
* u5 V/ R; I, b4 x3 r% U4 v                {( |# n4 L) W2 P5 D1 S
                        6 @& y* J) y  R8 R
                }
: A  ^, ^" k( V9 A                */$ b% P1 H7 y6 F  Y( P
                //comment out all methods, N=100000  202s                - f; {( F9 c  i
        }6 p2 G) Q  t# u8 ^# T6 _$ \

/ `# T3 p. n! t* [; B" g, r        delete []b1;
/ s1 [* ?- Z: A/ J; V        delete []b2;
( a4 H2 ^0 \! ~' g

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?/ t& K- H; w& v  E- ]* M
  f% E# F4 |% m/ D2 V3 A
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
7 w" }9 V( u' L9 ^; O
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
  I7 @8 }1 V9 g$ n6 W* y' \$ _瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
. {& ?. [% }$ c4 D
( z8 N, b! J9 Y! ^! k你第二个试验里面的j在循环里面又重新定义 ...

4 d2 X, R% S0 f+ M4 [- r- G1 l内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
9 e) p6 ^5 ]+ Z7 e( N% Y. v- _
' t2 h% `6 O# Z9 i* S: n* E不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:167 r' T6 {- U  T, j
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
$ R) p9 y5 Y6 U/ I. f& r+ ]1 Z0 Y. C" |
! V" h1 [9 v4 h; @; c不和它 ...
4 v, F" w$ P' S) ?) {

0 V2 d4 J& J! P6 M0 _3 H% k6 n不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。' L7 S' t& r5 T" M6 q! p
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54; w) L% F& R+ K' C( ?- x5 ^* q
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
7 a2 n6 l( s) Q% h$ u$ [$ L{& t' X, h6 g1 E4 J; g5 g
        comp temp, xtimesy;
6 G$ O( e, H2 C) g; u' F
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
1 q9 O$ G, R; C内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
* i; y4 A5 z1 L& |VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
+ @/ I6 `5 z! R理了理思路,重新做了一个测试。
9 I& ^. f8 t( V, i. _- p做了两个 vector 和 两个 float *, 都长 100000
5 \9 b! @- ]' T$ X; D外循环 6000,里面先做随 ...
% d6 C* |/ r9 {2 R
这个时间是从哪里开始算的?
5 u! g- s( b% Q% F1 u2 M我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
$ R( h$ \! Y4 G1 q, H* a9 X按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:396 W+ A' ?$ M( a% U4 l
这个时间是从哪里开始算的?, }7 ~0 Q! a0 Y  Y6 v
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
% R. N5 \' B( x0 [
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。& L+ W& m8 H6 l. g
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。5 F9 L; |3 v) L, ~# W/ w# X4 ^
与此对应用数组(指针)花了2S, z  X% q8 e  ]7 i
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
  i  c7 Z) t1 ~' f6 Cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB): }  n! g- }4 }( d
{
' a1 i! x8 ^9 Q+ h        comp temp, xtimesy;

: o9 I' j* `2 [# C" K+ p3 |我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
/ ?3 P9 b2 A* A4 k
# T" }, W- H* a- j* i) A2 r. e0 q6 f
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29/ S# n4 e+ p3 o; |: d- S6 G
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗+ X, B( D9 N- c0 j( Y9 x/ p3 s( t
- k1 [. ~  G5 s! q
...
& H7 i! M8 ]# Z! }
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
& @8 @, ?- ^, M  `. {1 x# }) x4 R4 G1 l/ }. w6 N( H; y3 I4 R
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 " ]9 |8 j9 b: f! W- Y' W# H5 t
6 ^' H  r0 B0 ]
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
- ?% V: |. e. N  @. [& }9 Q有空时我会试试 SIMD和并行,看看能提高多少。! `! p8 a& [2 o4 l( Q7 q
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 " I, q4 ^1 |6 u+ h) W
谢谢大家的讨论,I learded a lot.  红包已发  , Q  O5 n  h) `+ W
& ^6 H! C% ^$ m+ Q
) E7 V7 F5 x  g

$ N& \. F" K- w/ [6 O
% [/ {) k$ z  x. P5 }( K1 D# t- K




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