爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
0 y5 Z# M* G7 F0 C% Y
  T  o" s' ^. [( ?( @# N: `: N自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
3 @( y* t$ J: W, o* }! u/ @2 \: P
" W$ t, p: O: A2 r/ e4 w6 s  W* J速度优化问题真的很有意思啊。3 D3 r& X$ k4 K) ^7 Y( {1 u

3 h5 o' H/ p" B9 K& p  L欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?: H7 H1 Y% a! U% Y7 K
把代码贴上来看看?$ O, Z$ e  U8 e. _, g4 U

9 Q& s8 I3 ^9 I$ X! W难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 & O" b0 N4 b# o9 J2 x) z% m
数值分析 发表于 2022-9-24 23:04" a3 H6 e' u, c0 ^& B& r/ R
拉下来?拉多少?
4 c$ k( [" ]6 ?& H2 \0 o# D. O把代码贴上来看看?
5 p) [" I7 g3 B+ h2 }9 s
: m% r+ U6 n2 ?/ `% d1 e; y5 i. e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
5 e4 l$ W& V; W  W) R{
" ~8 U- b5 h$ k( D        comp temp, xtimesy;* S+ i2 a9 o/ t9 }, O: L
        xtimesy.re = 0;
3 c( p. {% Z% z# z5 s2 ]0 `5 G4 k% z        xtimesy.im = 0;6 u5 s) i- l2 z, N
        int j0 = lenB - 1;7 Z# F# ^' A- O( u
        int    i, j, i1, reali;& V3 m/ w6 h( h' i3 l
        if (lenA % 2 == 1)" q: m/ e5 `: Z' B+ I8 F3 H( y
                reali = lenA + 1;
7 D- Y4 O; w: t1 J" D' b+ j) o% y        else
: m1 `; b! P; o, l- C                reali = lenA;/ I  M# u& k, z: I" R
        reali /= 2;
. ]/ E+ E5 m5 l/ k% a9 K+ G  @% A5 ~* ^+ Z; T- r' o* e) E
        int nconv = reali + lenB;+ ^) H+ g* u3 o
        //#pragma omp parallel for; [7 x6 X  p; R
        for (i = reali; i < nconv; i++)
1 C6 t% p) m: W7 L/ c& C        {
1 m) T% o. i6 _& J5 |                temp.re = 0;
# _* E/ u5 m5 D7 e                temp.im = 0;
% W* `& w; E8 x- k                i1 = i;" N  ~; ]- |9 q( f5 J5 a8 f8 D# f
                for (j = j0; j >= 0; j--)
! U+ [+ b3 U7 j5 b) j                {
- H9 Y0 w' e" O1 y' u$ B3 v                        /* floating date operation */. C  a4 O, s- n1 b5 L0 `* H6 H, n  \9 `
                }

& n+ Z% T6 R6 M7 w# r        }
+ G& x7 [- e, A3 D}
7 w# D* M' Y6 m8 F* G, V
2 F% W. e, @- pxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样' x1 W/ `8 q8 `4 c( @$ ^
* i7 @* n) M# G! F
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
4 `2 w2 I. y2 X$ v7 {现在call xcorr 100次,耗时78s.
9 }) E& N9 f0 m& ^+ h1 D  Y
5 j+ m; G) @/ t) Y6 {如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. * R$ ]3 L4 L$ g$ D! ~+ @" i; r

& G% B# n0 }) Q
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33; C$ Q6 ]( U9 c6 D
Maybe Debug mode?

1 ?! p7 s& L; v4 ?; B3 m+ w/ n
) o) z( ^  b" o' j5 o不应该,看我上面的回复。1 i& M  F( e! b, Q5 _, V

' {& x7 l$ K4 J1 ?, t: A我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑   E! K* A5 l( r  M1 j
雷达 发表于 2022-9-24 23:54
5 q* w' \8 H5 p7 a; r4 Gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)& E+ F! Z5 ^  A. _# O: N
{
* G% l' e$ D& k7 F% Y9 Y; F        comp temp, xtimesy;

+ x% c8 Z$ k& L! ^6 R
) @7 i! e" W6 X" \6 z: e4 m这个不是这么比的吧。。。
6 {, O4 L$ `( l% J3 c( E% T+ W
- m/ j' p) H9 _  |6 V( t2 a  T您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。+ E9 [$ t) D& d3 M0 d
( J6 ]6 K/ s$ H0 y. i
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
, a; ~4 U. D  F! t, F0 {
数值分析 发表于 2022-9-25 00:20+ M7 u* c: h) l" Y& z) [
这个不是这么比的吧。。。
$ F4 d2 q7 B6 ~2 D- @( j) R- g+ `1 j7 E/ T+ {. p
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

3 ?/ \  |2 N" A: k: C4 |) E+ T3 S' ~( `* y5 ?
有道理。8 X/ k: w1 \& a0 _* y5 c# |
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。5 O" E4 E4 {) P. d6 c

& Y. N0 v) d3 t7 ]* }) z我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
8 x4 |( _2 G" N* e有道理。8 r2 Q+ O  l, u6 F5 _" Q
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

  }/ }! ]! |1 j* D2 Z" U: P你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
9 v- r7 l6 u8 p( B- b6 e) `4 ?Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:201 V$ U& i' b1 f, U0 |
这个不是这么比的吧。。。
" h# m$ b+ F9 o' h9 }$ f2 R2 Z2 j( y. G- |% z; b
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

- d! h& h1 L5 E
% O/ v6 I: [# K' \现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 , u2 X9 X1 V5 }
沉宝 发表于 2022-9-25 01:48
2 A; j* v9 w( ~: n# P& L现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
, D) @0 d4 p, U" z
. g! L4 C! I! S+ f; E) b/ i& W
是的,兄台说的对。% U0 q  v" x9 @# ]: w! K
# }& G0 ~3 M" C$ x) W. |4 @
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。* ?/ J: B) b1 r- s9 h+ e
0 C( i/ u; a) [* ^. }; N6 J' J
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
  o. O1 p: X0 ^6 {3 N5 Y  X: w2 D& ^/ G* B( c' z
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
+ o' Q; L' i. T, z* t: x+ V& s4 t
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
* H8 K" a$ R2 @. K- Q4 O
沉宝 发表于 2022-9-25 01:27
( l- e0 X5 i2 R+ _( _( h你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

0 x! [% Z( D1 P$ d! q3 O4 [" ?) `6 f/ ]: S* M
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
/ O6 U; h. {+ ]& z$ B" N) T  j; @' Q
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
6 e7 U( ~9 F. r: N/ ^又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

# [( l& F3 ]: s: W7 l. I6 ~+ |时间差一倍的结果可以接受。
: e/ P8 G4 v* R: K
# D6 v" z9 I# `" J/ ?% V! \9 O你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 $ C5 I( h& S: x- O; W  z' k0 G  ~
雷达 发表于 2022-9-25 04:47
" ]9 D3 w" d4 ]2 s. n又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
# {# n; Q8 `6 D4 S- n; P. D/ l. H
' P3 F2 g6 I! r/ r& d4 D. S  {

) b$ i# j7 t/ B
" I. m& q+ T3 S  {+ e" ?能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
3 o9 O9 L8 \6 s6 Q
数值分析 发表于 2022-9-25 14:58
) {; ~; N3 u2 J' X6 O0 e能不能把这个也贴上来,看看和上一个有什么不同?

% U4 B; X+ W# z  u4 m6 r理了理思路,重新做了一个测试。: I4 K' L! F) Z% ]
做了两个 vector 和 两个 float *, 都长 100000
; F1 _, s2 e! }; }! E外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
+ a9 u: {3 N) l8 b9 H8 Z: f/ S6 ?5 x7 e0 z* Z" H  x& Z
内循环试了4种方法,- G8 T7 `4 |! h* S. R8 w
1. 直接调用 vector inner_product 247s
4 k7 T( L4 _; J- `: v5 N2. vector 循环点乘累加 237s- l5 n6 A8 j, p. ~0 Q
3. float * 循环点乘累加 204s8 \2 x6 }" V4 U$ {# t0 V+ m
4. 空循环 100000 次 202s
! G; T% W0 P! G8 c4 r
- L% W, G/ ^, O& X+ d不做内循环 200s
- Q/ _+ R& V9 f( H) J9 m/ c
! P& c1 P: F: v- u+ w/ ]2 J你昨天说的对,内循环本身占比是很小的,大头在其他处理。, i7 y5 c& W: H! K" ?
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
0 E4 R& k1 V( A' |$ {8 A! ?+ l+ y+ {: J  y! i6 F
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 S+ q1 r( H8 R% q- Y& ~% g. z
9 u; O, _5 }3 ~* H$ l/ b; R( u
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)) ^8 q$ |- m  M- ]) |- F% ]& w

8 |# Z5 a$ t% t2 Q" m
        std::vector < float > vec1(N);' m/ ?( [& Q8 Q8 E2 p
        std::vector < float > vec2(N);
  _6 ^. F% R( `( ^% U        float* b1 = new float[N];: g- t" e7 s6 o* A! w
        float* b2 = new float[N];: H: O5 k8 d8 a; L/ {' S8 L

4 l# g( @: d' Q7 A4 U) L1 n        for (int j = 0; j < 6000; j++)
, ^; o& v2 Y$ d( b; k        {. w, y( y7 G8 K; ^5 g5 Z' J  m5 W( t
                std::generate(vec1.begin(), vec1.end(), []() {
& K1 t5 a6 q% {8 }! o                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
# X* l$ w2 r' l8 q! D' T9 E                        });
6 Z9 \+ ]3 `0 ]3 S  s: I- ]
- d% b% h4 A2 \5 V                std::generate(vec2.begin(), vec2.end(), []() {
" T! U$ d/ a  t" n( I3 T& T                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;* k7 x: {3 t! x# R9 }* k/ Z
                        });0 F& L5 ]3 A$ j! P7 ?- }" V

0 a1 @6 |3 F0 @. x8 ]                for (size_t jj = 0; jj < vec1.size(); jj++)
+ Z" A/ L4 Y" o) Z7 Q; h* _; t                {! C* G- Y: o9 j3 r8 o3 ~/ ]; N
                        b1[jj] = vec1[jj];
/ R5 I+ N9 W% y  s# N7 o* n+ c                }
" \  m9 W& |! S3 R5 s: k9 ?1 v
1 m( S* x3 ^- I5 U* @4 h                for (size_t jj = 0; jj < vec2.size(); jj++)
" V5 ], E  X8 n6 b' c0 C* |                {+ @: r! O( s7 L* P" Z
                        b2[jj] = vec2[jj];, H/ d8 E/ j! k. t0 w
                }
- m9 A. p; ^; r4 n
5 h" _3 V1 ?& X! k; X- N* A% o" T                //Method - 1  N=100000 247s  
$ p' p! d% E- b8 U                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);+ ~! }1 J( r8 e% f8 U4 a
                                
* y" _3 ]2 q! |# }6 S                //Method - 2  N=100000  237s
' J: s9 ~/ m3 c' T3 J                /*
: T8 k0 C/ s: ]$ y                for (int jj = 0; jj < N ; jj++)  h5 {1 F2 @: b- c5 p$ p
                {
/ M' h! L2 P% \# f  E  }( U7 z                        fresult += vec1[jj] * vec2[jj];
6 O5 x7 D- L. I6 ]# N                }
/ `3 t# ?3 H1 N" y4 a                */' f  ^0 M5 [$ F4 w0 _0 p" h5 n
                                . M3 O3 T  I& `1 S) n% g
                //Method - 3  N=100000 204s7 H: i" l/ ^( L+ g( l9 o
                /*3 P0 ]7 X. y  Q: G
                for (int jj = 0; jj < N; jj++)
  G- a, D5 n6 K1 [" C& k( I2 e7 `% a                {! M5 r& _; c. A) q2 O& P# G$ `! I. h
                        fresult += b1[jj] * b2[jj];
& h# E. h' V; |                }) a9 e, ^/ o$ O
                */
7 T6 ^' q0 D, T: C8 U: c  A, i8 C( A6 [4 b9 s/ `8 Z
                //Method - 4   202s5 Q' ?: x: g# K0 z- n- ~1 ?0 q# ~
                /*
. f, v4 d0 b/ W* n3 ~( G3 S+ P8 k                for (int jj = 0; jj < N; jj++)
* w0 Y) G, P9 I5 j& b4 {" J" t                {/ j& v# j. |4 E5 p) f$ _/ o7 F1 k
                        & d' Y3 o2 G# s! {
                }
9 e3 }5 v: c* E$ Z9 [7 n                */
. Z- O( I6 e* m7 B. s: c                //comment out all methods, N=100000  202s               
* ~4 @- K, C: l" l6 `+ L: u        }) q/ E. [2 g8 h# @6 t, o( H

$ ~* K  C. l! [2 ~        delete []b1;+ p8 I, i9 p, t. g! }8 U4 |
        delete []b2;

% |9 d# \) q& ?9 W9 |& x, D# j: d
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?# c3 C3 g% D$ t- F2 M

6 Z  f8 \2 n- y! V你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?, J9 E$ i: ]9 H7 S8 A7 X

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15- V! P7 r. b$ x2 u) E" h, f
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
2 V' L, [- {( d$ H* q+ p+ y# _) b: f: `
你第二个试验里面的j在循环里面又重新定义 ...

5 h7 F0 ?7 J8 r/ R( J$ _4 i. L内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
. Y7 U8 T1 q, s" L$ @. o5 Z/ h0 t* ]% A2 Q8 [8 V
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
; o6 B2 H' n. I3 H; n内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL" A( D  H  Q( K9 L7 Q+ p1 v
6 q6 X% H+ f. I4 k
不和它 ...
* Z0 C& ^8 m0 v- r
# x1 X7 m: s: s, [2 F/ S
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。. [6 |1 N( \& Z' _
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
* y! v; M4 U& ~# \+ D: L  ?6 l; Ivoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ m9 W# f# n/ V" ]1 B{
. u/ T, X6 N" d  }+ a        comp temp, xtimesy;
, A" e; A# Y8 Q9 r* Y& T
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
  j$ M- z2 v+ f5 ]* e8 L1 |内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
$ v. ^; Y9 H" ?. _; [) jVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
2 Q/ O5 z- `  _0 f1 @理了理思路,重新做了一个测试。
( n8 o% [1 H8 p9 K7 k+ B( W7 C, W; I做了两个 vector 和 两个 float *, 都长 100000) o8 R; R0 b9 W3 ?9 j4 P
外循环 6000,里面先做随 ...
" s* O1 E" O# n7 _6 ?( X$ O
这个时间是从哪里开始算的?5 t; w4 C- x% t/ |
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
# q- {1 ~6 G! o2 @, h" l按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39% V; k: X: V% H+ N/ X1 o+ E
这个时间是从哪里开始算的?1 j, F# G0 e" Q! Z- v1 g* }
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

" e/ }! {5 m, H! s我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
( d# V! x) m! ?1 Z' b你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。6 \, X5 J; |9 E) v
与此对应用数组(指针)花了2S
3 b0 r- {( C& O+ A你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:546 m) _* U; l" X2 e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- ]- x* s" I9 t{( C  G) m7 @3 y7 K" T7 ?
        comp temp, xtimesy;
$ u! Q0 M1 ?. a6 z
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
# k7 I* U, {( T# n4 g+ A+ X3 Z' }0 q* ^0 g; a' l4 Z8 s

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29+ e( I. ~* J$ `
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
$ s: X) A" N, D  }: {5 F, z; v/ z6 s7 r4 n8 f% S1 K5 s9 `% K
...
8 t1 D" W% G! `7 d2 R
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
1 u# s7 a/ ?) u6 A/ H; F' `6 p* N! ?7 r/ u  p; K* w
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
, ]3 E, U7 f4 f
7 t4 G  F" f5 m" B是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。. X, l; Y  y4 G( {
有空时我会试试 SIMD和并行,看看能提高多少。2 U0 p2 a2 i: @# G9 {% f0 T
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
% O, D0 n. G2 N3 [- k0 D  Y7 n谢谢大家的讨论,I learded a lot.  红包已发  
9 `% n- K9 v) y, i5 ?) b' I+ l
. d9 s) q! ^) A) s/ f
( j2 B, E: D* o" U: B1 {6 h
5 S: _& R( G  W; P1 {0 V% I1 W$ E6 B; J/ L: s' m. A





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