爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
" `* C) N# T- H. H2 ~! g! Q: l+ d$ H( x( f4 r2 p+ a" @6 v$ d
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。& ~) ]% h$ b1 y! f3 d5 P. s

  {* i- a6 p+ \/ [$ a  V速度优化问题真的很有意思啊。
+ D0 `2 D9 `3 J8 D" x) @; h) W& z! d& B7 ?- e5 I& l: P+ x/ P
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
! y8 u  k+ e4 P把代码贴上来看看?& [" ^* W2 q) H! V) s% {* C: R3 m

. [% g. k: x. a- e) W2 e4 d/ @难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
1 r1 i* g" |$ u, t* L
数值分析 发表于 2022-9-24 23:04
0 u( |3 I* j0 Q+ o4 l( X拉下来?拉多少?
* }/ s# H7 v: Q5 `* ?# C把代码贴上来看看?
$ |( [! \! j! H
, x( E& K$ m% Z- n. t
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" l3 _/ I3 T9 p5 M, E
{
5 r: Q: Q: i3 D  k% r+ F        comp temp, xtimesy;
- \4 @9 _  M, b        xtimesy.re = 0;# X1 Z4 @& L2 L4 K0 u4 ^3 A
        xtimesy.im = 0;9 y4 Q! r) q  P, w* v: A
        int j0 = lenB - 1;5 G! E4 h5 A2 y+ x! i  z
        int    i, j, i1, reali;  z% R6 d/ Y8 B3 i' J
        if (lenA % 2 == 1)
) t- h5 x: B: a3 {                reali = lenA + 1;
/ T5 b# H( B# G' i/ I' c        else
! y4 l  L8 H" ]- U                reali = lenA;% r' y7 P' A. M- f3 I9 r8 N9 A
        reali /= 2;4 ~6 [5 T# t1 J2 j
4 Y* k7 T3 _$ P
        int nconv = reali + lenB;
8 F8 k7 _. {& e4 B2 p: l! Z  C$ d# W        //#pragma omp parallel for
% b2 ~$ l4 B) b) G7 x, B        for (i = reali; i < nconv; i++)1 L' F1 }* c9 L' l
        {
9 T7 t/ G  D* ^: z6 T" G1 B                temp.re = 0;* z1 H8 @: E8 o. _- p/ h* E' z7 O
                temp.im = 0;
" Z5 }6 T# T9 L  |/ y7 r                i1 = i;
) V6 E& d1 p6 @; c% K                for (j = j0; j >= 0; j--)0 n3 w  m2 ~- T" v8 _* g
                {
" [/ E3 g  x7 O                        /* floating date operation */. v9 L* z% [4 Q; o5 o, S& W: G- w
                }

. K9 J9 D) p2 _) N/ d        }% Q1 i. C% n0 N' t
}' o& ~" _7 ]) \+ {
7 i. b9 E& u4 m' j
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样; r& w, x& p2 C
8 ]5 @! r/ D, |6 U: e0 t
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。. v$ S! k  w1 |) h
现在call xcorr 100次,耗时78s.. Z. _; V* f9 N) C3 [0 L

! t: \1 H$ W% w' y* p* E4 _7 d( G如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
- C% s  K* q; j+ ^! f9 v9 i2 m8 }  \- |8 ~, V1 V# c

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
7 U, r4 r" T- ?9 ]5 DMaybe Debug mode?
. O/ {; M; I* B7 y
: X: n/ K! Q# R2 g' @2 n, v4 W/ i
不应该,看我上面的回复。( _, j# y' x& m

* ~7 U9 q# w: M( w' w* f我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 1 ^% N) G# a3 r# Z5 O8 J5 s
雷达 发表于 2022-9-24 23:54
9 T% z* b8 `; x4 J/ Z# x3 x7 Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 g1 k) ?! ]3 }8 X. u
{
4 ~5 t' T, P# u! b2 Y2 }        comp temp, xtimesy;

: @, D6 q2 Y) o. |' b5 `* [+ R  d# F
1 n1 D" }, I; g/ S+ d1 j. i1 W这个不是这么比的吧。。。
3 A7 }! k6 @, E# B* b
: x$ g8 k$ z+ p& [- p- l5 t您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
# D% ~: N0 C8 ]% D+ o* c
) N6 k( o, s0 e" }/ ?( ]$ M! Z4 ~而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
4 }/ g( z/ |: Y
数值分析 发表于 2022-9-25 00:20
' r6 l( S6 G4 `这个不是这么比的吧。。。
8 q8 u) s8 e8 @. ?# W" T4 K6 P
6 m+ R! J9 S, D' z7 W2 B. F0 ^  M6 o2 g您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

6 I& ~! P2 T# z3 b" n3 B. |; H5 C. r: D  d
有道理。3 C+ R( d' V" M# L
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
3 z9 _. l) }" R. r; X. A
% Q5 ?/ @# O+ {+ V6 ]. I* R- f+ h7 D我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:468 R; e; }! P+ ~3 h0 W+ `
有道理。+ _; r6 z3 K/ |1 [+ F; F
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

* M' @& w3 D0 C3 F$ ^) K  w: F) r你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多; B" u. o$ }+ k5 O
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
: F" u9 T, q; W0 ^4 K& h这个不是这么比的吧。。。
6 R3 \) X9 o- g, W( B" K- N% g( M& b7 H% g- _4 V
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
8 s: i+ O3 @5 t! O

" J( X- U' D3 l4 c3 N2 \" |现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
$ U- H- Y" C7 j
沉宝 发表于 2022-9-25 01:48
. v* I9 n, Q1 K& `( t1 |0 B现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
, y8 p5 t, `, p* `  @" B4 M" l, \# a

. S2 Q/ Q2 u2 R" g是的,兄台说的对。
: N! g' J  x" [4 e- R- ^* n: Q6 }
5 i6 W; ~' K+ A" S) x2 ]其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。7 A* N6 \7 ], i9 `& q' k5 D

) e: g/ ?9 _5 f" O雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。- u. r. K* ~% o; {* b
7 g# u8 q7 ?' P- M2 F( r
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
! j# N# U" f7 v; S) f% E" {: r4 }" i* y. B1 `) f! v
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 8 Q$ @! k7 R& i; ?4 S
沉宝 发表于 2022-9-25 01:27
* M  }0 F/ Q7 X你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
7 f0 p; c9 Y" e

/ t$ S9 M0 g, Z" U- L又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。, {7 ^6 {' ~' i4 l5 C
" N9 s5 [( h4 g; V" ~% Z: ~
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47% X  ^3 j1 z1 l: S) \' Z
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

6 p, b8 Q6 {# F时间差一倍的结果可以接受。
! l+ Q8 u7 v" e$ u1 k- A
: c% x: l  Y7 E% {/ G. }你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
1 f( @9 D, i6 W7 t* z& ?: f
雷达 发表于 2022-9-25 04:47
5 h' ^6 `# u6 `1 d% [# Y8 r又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
; `; r: m. S, M, E6 y
0 R4 E' T' ~" Z; \" _

+ B0 N2 ]4 W4 ]" H8 I+ Y! Y8 T! O0 j! ]9 X3 @  p' ?" O
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ; Y' \4 `; T& q! P9 D- c( y
数值分析 发表于 2022-9-25 14:58
4 {# V! k9 m7 O+ S$ C% T0 S' E% y$ ~能不能把这个也贴上来,看看和上一个有什么不同?

. m9 G' G9 c, v! {9 H  f理了理思路,重新做了一个测试。
  ]$ }5 M7 i$ H* Q7 o做了两个 vector 和 两个 float *, 都长 100000  R5 @5 e2 D: y& v9 A
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! L2 e) e3 o/ I2 }! }1 i
0 ~6 {( m# C( r# S内循环试了4种方法,
+ d) V1 v3 W$ T4 j2 E7 ]4 C1. 直接调用 vector inner_product 247s
; b, m  T$ O, r# J, F2. vector 循环点乘累加 237s
/ b$ `& e, L0 a/ G3. float * 循环点乘累加 204s" w; `, d% i/ _, Q, V% U% X
4. 空循环 100000 次 202s  y0 G1 L2 l7 K

) O$ P" @$ [4 u, d8 T不做内循环 200s5 @  B8 j2 s# w0 I$ A
% K9 r" F& X  p7 l6 l
你昨天说的对,内循环本身占比是很小的,大头在其他处理。: }: y7 T3 a! F+ l. A
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
1 [! ]$ p2 ^. Y( H, Z" C$ o$ a
3 H' Q% W+ Y1 ?# e至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% j* I/ H9 `6 p5 s  x# a7 F( A0 J

* s6 R4 B: q! H2 a+ e3 ~# c(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
( D  k. U- f6 [  t: n
' L7 [0 B! s% c
        std::vector < float > vec1(N);8 j/ Y' A. ]8 S+ r( i; o' b% l
        std::vector < float > vec2(N);
  p1 Q( R: W3 Z        float* b1 = new float[N];4 [; g4 g; |7 ?' S' V& G
        float* b2 = new float[N];* P1 K1 O" z. u4 o# W

" B+ A7 ]% R# Z" C, F        for (int j = 0; j < 6000; j++)4 d! D3 |! w, C; S
        {
4 B# t$ D( s8 q2 q                std::generate(vec1.begin(), vec1.end(), []() {3 r, ~' l2 D* c# C
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
( U8 I3 x* k$ u5 y, H                        });
& l  t$ j' H4 n  z- t* J/ c' O, c& d) M2 R5 E' `! t
                std::generate(vec2.begin(), vec2.end(), []() {
3 F/ j  M/ I- g0 I8 ~                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;! q1 x8 s5 Z; R5 u9 w4 c4 U" A3 [. @
                        });
( Q) A& ?) g+ ]3 r- S' e
- P6 Y# v5 K" ?0 G4 p9 S1 X                for (size_t jj = 0; jj < vec1.size(); jj++)9 q) h2 j5 K/ M% d2 _) B) S
                {
  e/ j$ s  |( |: S4 |2 ^, n0 c4 N                        b1[jj] = vec1[jj];9 r, p. Y  @: }- }6 s
                }( u/ M# e( i4 l% R1 e- v
! y+ o) f) P, J+ ]
                for (size_t jj = 0; jj < vec2.size(); jj++)8 l1 k+ x& }3 N% w: x, J* q
                {
" E/ r+ \+ Z2 f& d: H. ~3 L                        b2[jj] = vec2[jj];5 T& b3 |: g: ~3 K, A4 u. {
                }
7 r5 o/ x: B$ @- X$ ^0 P
- Y  v& w7 M" [8 B                //Method - 1  N=100000 247s  ' B' y" c7 J! z5 d& h; c
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
) z7 @+ I0 A6 H' ~                                
7 w( ~2 F- y& p( m0 ~* |9 t0 Z' c                //Method - 2  N=100000  237s
* M3 `* h6 ~* j* T8 z2 c: Y                /*
: r: B. K, G6 h' T                for (int jj = 0; jj < N ; jj++)
8 ?# ?; r) s; \- b- o                {
% H& l% i8 s  T: E$ ~1 L% @                        fresult += vec1[jj] * vec2[jj];
; q0 s2 z0 l, T& Q& k6 a                }
$ C+ o7 c/ ~$ A) ]9 d/ {                */
" n$ `( z4 v- |! ~: C                                ' c4 ]# a1 ~$ h7 b9 M( m) N
                //Method - 3  N=100000 204s
3 e1 t: ~8 }" _4 L" N! N' t                /*
0 d8 k- [$ z8 L" B+ @5 S# a$ l                for (int jj = 0; jj < N; jj++)
2 E5 U) f3 ]- ]2 a, R0 D                {
2 M/ M" c. m' Q: n0 F7 i2 f2 N                        fresult += b1[jj] * b2[jj];
# _# _  X* }2 G( V4 G- Q# A                }/ H/ ~- a; y$ x  W5 k! r
                */
( k: K1 ?& z: ?- u  ?# f+ o$ j8 @/ O2 k: P
                //Method - 4   202s, o" j1 E, [8 |! D! \1 E2 h8 a" t# N
                /*
( E) |4 Z" h5 R                for (int jj = 0; jj < N; jj++)! h5 m! i" q4 @
                {
  |  i( ]! E: d; |7 Q                        / q) A( {: q( P  C" j
                }. R" ?$ @( r2 r6 p8 X* b
                */
. j3 K* v0 Z3 {" U/ H7 x7 X7 x                //comment out all methods, N=100000  202s                ! r+ T2 B2 t/ T) u; v, P5 H
        }* x: S6 C' X3 b

- f$ v: U) O% `! Z. V        delete []b1;/ [7 w7 v* r4 C% P/ k, r, S
        delete []b2;
1 v  _3 j) \. Y7 S

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
0 w: o. G$ M  V1 j+ ^7 C) F! K: r& ^4 Q3 T2 \7 ]7 ?0 a# b
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
. h9 m% b1 i) c- ~: v
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:150 h3 o% l' l7 x  Y, ^5 i3 Y6 |9 h
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?& }( H$ B# E3 i4 C8 l" |5 |( T* t% \# b
% ?8 R+ [7 q/ z& L+ E7 B
你第二个试验里面的j在循环里面又重新定义 ...
2 I0 I. ^( R: r) P- B
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
* I! i/ c( \4 G1 N9 f) c, x, L% R) z/ h* P  R( L
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:161 z& j/ q7 f4 B6 D
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
; M1 n7 h; J. G# F( J7 L) [
3 U( `, J2 \/ ?不和它 ...
/ t2 s2 @2 q- d- X5 r0 D

6 @8 [2 a9 _: H# Y. D不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
8 b6 R7 I& q$ D5 A! f  i. U$ L后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54- o7 n- N: R* Y* y$ T" i2 y
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
: k  y8 ^, q8 ]$ A$ f{
% M9 J/ Z0 ^4 Z: s% o/ S1 t" Y        comp temp, xtimesy;
+ r/ z- ]  G# Z9 y' f$ @; [$ z8 T
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
4 V+ R, N7 `2 b9 S$ E内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?: L& Y' g7 @4 D* j) Z
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
8 q# ~. j0 U" I: N2 p* n理了理思路,重新做了一个测试。
" t' H! t$ G* }6 x; j3 s6 B做了两个 vector 和 两个 float *, 都长 1000002 t" T) q, z3 t! H; ~2 s
外循环 6000,里面先做随 ...
" }/ a- B5 |" }+ q5 U6 d: c3 r  U  U
这个时间是从哪里开始算的?: `/ d1 W  [( _. g9 }4 f
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
, M" d  {' L1 i按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
, O! T1 k6 c3 ~4 M这个时间是从哪里开始算的?! n7 J8 ~4 f. E$ ?$ N
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

; n6 v( \' N+ p" X1 d7 ~" K我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。) V3 d* J! j+ L  B7 c8 b
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
/ y1 @' P# d* c, Q; {0 y与此对应用数组(指针)花了2S
9 S  a" A7 A* h% L, ^) e, n你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54- F; o2 e. G0 L# g7 w' R7 d
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)% \) M; @- E7 D* O
{6 G2 {' f, K. T+ m
        comp temp, xtimesy;
  F, R8 l: ~' P/ q( {
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗0 C* U* [1 m) u4 x6 ^+ V

* r' X9 B9 s0 A0 [0 p+ {0 I
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
4 f) v4 ]" q; m6 X# R% w% Y# {4 p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗* Y6 y; F, k4 S3 s' A: O9 h. k
" ^/ ]! x4 [, O! C  ~
...
& q  f; `5 x8 o. q/ b9 S
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
$ |% X* f7 \) s+ B0 U0 z* N/ i- O2 L/ ~  f: n* ]# @: W8 n
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
# N7 B5 _! l' }( q$ l% y3 B/ }0 o5 N* k8 |. s; I
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
/ f0 P- a. n- F+ _. _有空时我会试试 SIMD和并行,看看能提高多少。
* c3 I% z7 q% W* \" R) O6 y: r% I过去7、8 年没有正经用C++ 写过东西,没有 sense 了
3 A- {" L: \7 {/ u谢谢大家的讨论,I learded a lot.  红包已发  
. R) ^) \, [: k4 O# G2 I! j  Y* C* `7 Y1 Y7 Q

. O- x; ~' y) t# G' C* I- U
  a3 @9 M+ h- G- x9 s; M
9 t8 ?8 R# s9 f1 V( K" X




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