爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
5 B+ X  m7 k4 B6 J5 \) D* C% X1 A! i& E6 \* B' O0 H
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。$ f, p( }3 m6 u6 g8 r! u
) y" a! \9 |7 [) f7 U% o+ F9 T
速度优化问题真的很有意思啊。7 e, m5 k3 W+ d: W, V; T

% a  o, ]! x; D. w/ h欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?+ \6 Q5 Y5 K( [0 A
把代码贴上来看看?+ m2 ?' y# d' T8 E4 y/ m" @* ]

9 G% h- c1 J  K* w难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 9 g/ H0 Z% h  K* v" T
数值分析 发表于 2022-9-24 23:047 v/ n1 J: A2 j
拉下来?拉多少?  c9 v3 B4 X3 t9 M6 E; Y8 q
把代码贴上来看看?

( |" ~; `  x0 D+ b. G4 A/ D# ?$ l% k% j2 q6 t
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
1 N* \0 \: _- b! c; T{) i. l: ~0 n! [, i, \' b
        comp temp, xtimesy;
# c6 d* S" ^  n, _' q        xtimesy.re = 0;: ^8 v- E4 s4 @. r- Q: b% D
        xtimesy.im = 0;7 }/ r( W  Y2 Z7 G. \0 P* c
        int j0 = lenB - 1;- @3 U5 B) L9 L$ c. v$ @
        int    i, j, i1, reali;
2 |2 @; f+ w8 e2 f        if (lenA % 2 == 1)& N4 G# k) _  Z) e7 r7 y3 ]/ b
                reali = lenA + 1;
2 v- d6 b$ e) h: L1 P# |        else* h, D  h% [( Z% J. u# @) E: n
                reali = lenA;3 B* @5 ~( F, z7 t* i0 ~8 X
        reali /= 2;' ^$ `* m; ^- F4 \8 k; D! P
% _5 R; S, e: e6 s5 s
        int nconv = reali + lenB;" _( @; A% |9 a0 a0 B  @: l( N
        //#pragma omp parallel for& i- b/ H% t! q4 k7 a
        for (i = reali; i < nconv; i++)+ l2 p( |, |. k. t/ H- v4 a
        {4 }4 h& e( s  K% ]8 R% t4 J
                temp.re = 0;
' v7 l5 ]! d+ m/ l5 V6 M                temp.im = 0;
" d2 p, l# r! h# j                i1 = i;
, ^, x- N3 c9 n                for (j = j0; j >= 0; j--)
1 R+ A% W0 M" |' i, v1 N                {
  b/ x, t1 E( r) |! J                        /* floating date operation */  ]( H# r" @3 ?. e& E: h" v9 R
                }

" k4 z" h4 i* \& X" r        }1 m6 l7 ?, v/ j: R! c8 ?' p
}9 u1 `0 a' u: P2 ?: M

; C- i6 i/ U# o# Pxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
; H' k. h0 y# Y5 |( \4 g  g( {4 c! d0 c; |1 B4 }
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。8 _* P: x2 a9 U/ V2 |
现在call xcorr 100次,耗时78s.6 L4 y8 {7 F' R; p* `  [
0 I' E+ J" S1 B$ `; j0 i5 ^9 Q% z
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. / T8 h( i, f/ e+ O7 z2 Q
1 x6 O' T. |6 [0 ?6 p! Q0 K

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33  y, k5 M5 P$ p4 l/ `0 ?" k  \
Maybe Debug mode?

* P. ~0 N8 |4 K3 S; m6 g+ h: ?; {' G4 ]( l; J4 P( L4 y
不应该,看我上面的回复。6 y: `' n& I3 X, l8 T: n+ S

3 l7 u0 A) C+ K+ y' t: U+ `( ^我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ) Q& L% i# c1 e) S9 c
雷达 发表于 2022-9-24 23:54
+ b8 s) L" I6 F) A% |void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
! Y( d$ Z0 J, o1 _' k4 a1 |{
" m$ T( B" Q( f        comp temp, xtimesy;

- A) r9 k+ C) G0 D4 f; ]
# \  J7 Z" Y1 S  @" }# f7 \这个不是这么比的吧。。。
5 D) J' y+ A2 b2 q9 G/ l
  B4 Z; t6 O9 \! s2 Y3 o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
2 m+ f! J; y8 s; t
" y1 Y( R, B* M而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
' E) z7 y' ]# ^
数值分析 发表于 2022-9-25 00:20
( M) i" G. ^. p2 k* i' S这个不是这么比的吧。。。3 {) M4 `7 {' X; t* o; ~2 k1 W

! z( ]7 `0 q2 O" V您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
, }. j" O2 p5 U% R

* y% W' A  N0 [% Z6 Q! y1 w7 o0 \  W有道理。  t. L/ @- Q  ]' `% g9 h; u, S
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。/ h, P0 Y2 S) D% |4 @9 b
; U1 u( y" B) D7 _  e, }+ i
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46) ~/ ?6 [+ ~! A/ D; E4 `& Y  O" W
有道理。
5 g  I% N0 V5 _* L, i所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
- C" |; {  c. O9 B. v( T/ @
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
' U% |, G) y3 f6 c1 o8 |! s( b% NWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
6 U# V) x7 i+ ?. t4 I( V; e这个不是这么比的吧。。。
% |% [! f$ [# F% w- h& z1 R& {! X( o- x# M- v7 b
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
' w$ M  u7 n/ I# E7 k
- V& `  z& _8 s3 t# p+ Y- G
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 ; r, O/ Q' U$ t/ [; }* G
沉宝 发表于 2022-9-25 01:48. i! r: d6 H  ^; y# S
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

/ G9 t3 y) n9 V& n& t+ \: ?9 o' W) d: Y2 [
是的,兄台说的对。: t* Q9 z  d, J" G
$ |- t' k4 V$ y. K+ B
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
) {! ~( `/ C3 R  F; L
! e: x$ [. E& L- l1 `雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。" Q; J6 p7 b9 r+ }3 V
4 M3 C' V" V: r3 s3 \1 B
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
( t* E  _9 i, p
- _  B% n" K" @$ ~- i5 t/ @当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 . w: P' P# k* J$ t$ U5 E! ?# V3 C
沉宝 发表于 2022-9-25 01:27
' Q$ u6 O, R7 ?( {4 B1 f. i& S你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
0 y3 a0 _' z( h+ {) D* V

; X$ m5 b8 N) q0 _% S( n* I" s又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。, i3 v+ I1 A, E9 C; J' I
% |8 j0 o! c1 |( k, J2 n
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47( J7 j! H; K6 X1 r
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
( a. h3 l# U6 T( N# g6 I& d
时间差一倍的结果可以接受。! {# b; l1 \+ s+ r

7 b! K2 O9 i1 T. d' }你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
" @- [+ ^8 R6 t  z+ L7 Y# t
雷达 发表于 2022-9-25 04:47$ V8 x) n# b3 \% i: h
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
+ ]7 g" E. L; |9 L. ]

# u. @$ N7 D9 ^1 a' P/ [0 j
7 Y, \) \# r* W/ K$ V/ k1 U! |
; M, y) M* ?- u2 V% e! V) r能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 3 P$ v# q  g! ^  b, t8 j3 ~. g( h
数值分析 发表于 2022-9-25 14:585 |3 Z( e$ F5 u4 m8 s: ~5 p
能不能把这个也贴上来,看看和上一个有什么不同?

  C' |* I) ]. C3 u0 i1 o; x1 e理了理思路,重新做了一个测试。
% f: n) o4 C2 B$ W# Q1 k" M做了两个 vector 和 两个 float *, 都长 100000
) g% N1 q5 x7 t6 n外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! F5 e( ^/ R' k- b: N/ Q8 k& o; h* O
内循环试了4种方法,% P7 E) n4 c  ^+ N: g: X
1. 直接调用 vector inner_product 247s 3 P- L- g. Z' E/ P1 _5 g
2. vector 循环点乘累加 237s2 Z4 L. G6 c8 f  p" ~
3. float * 循环点乘累加 204s
: E( A! b6 W# D* P1 S8 t4. 空循环 100000 次 202s
9 U# _! G6 ~) b. K" ~* A9 b, E# H: n: {- b! f5 e9 V/ {, R, Q6 t
不做内循环 200s1 {4 a# b2 ^! v3 A0 c3 {

' n- L+ T, ^, \. a( ^, `: }$ K9 Y你昨天说的对,内循环本身占比是很小的,大头在其他处理。- f2 ~' {! t, w2 l
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。! s, A, r0 d) o' |9 y. y
( Q2 K6 L2 w8 @9 d
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
8 d5 S+ ]% A7 d3 q2 X% v+ I7 i5 M' k; b1 @% A6 T. s) ~; e
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
" H7 \+ D( ]: Z2 A! \0 @4 n6 v% X7 L# U8 {" o0 ]& N( Y( g
        std::vector < float > vec1(N);
4 {; |7 |7 S! [% Y9 _        std::vector < float > vec2(N);
: G6 e# ?+ \6 O" p! s+ ^        float* b1 = new float[N];9 Q6 D" A* J& g/ j" }7 E
        float* b2 = new float[N];
- K1 n6 \1 F2 X. U7 D
% h. J+ s" t5 \. F( u        for (int j = 0; j < 6000; j++): A3 B/ \$ l7 C
        {& K$ z0 O/ B, [; C/ @: y  s# y
                std::generate(vec1.begin(), vec1.end(), []() {2 s5 O2 \, S: Y" d9 j
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
% `6 h' p; O; T9 D. l                        });+ M  }$ M6 W5 t3 B1 ~/ i* B9 d3 q6 ]

5 ]  ~5 `7 ]) G1 K. t8 A6 ^. M/ |                std::generate(vec2.begin(), vec2.end(), []() {
* B4 E* I+ G- x5 S                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
* _: j6 C5 |) v% T# Q( g9 F" E                        });
" c. f7 d/ W, @6 C0 U. J1 O1 Z9 c  |! T! W: @# G
                for (size_t jj = 0; jj < vec1.size(); jj++)/ {) W! k3 k/ u6 l# q
                {& r; j* M1 `7 p* W  z
                        b1[jj] = vec1[jj];
, A& d& J2 z& t. g; z* e                }
& o. I6 W. S" ]: f2 q8 s& }. @  P
4 ]( y7 {) {0 H9 z                for (size_t jj = 0; jj < vec2.size(); jj++)
9 Q& u8 ^" G8 Q. V! N0 d5 v/ {7 ~, V                {
' A( i' f7 z! r* \3 f                        b2[jj] = vec2[jj];
3 ~! R$ ~3 j) C- R                }
# B* M: o# r# ^! m5 A
1 G3 e* V9 j! T$ X% }4 b* J8 e                //Method - 1  N=100000 247s  9 G9 V2 I2 \% g1 l) H
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);' W/ X0 o; z: G6 v7 ?5 R  K
                                - i( `( O. T* g! N0 C4 B
                //Method - 2  N=100000  237s$ ], [3 m8 L3 h( c* l
                /*' }9 @- H# ?4 f) K0 e
                for (int jj = 0; jj < N ; jj++)
5 V+ f; C- U1 M) C, _- I# @                {
/ l% h* B3 @1 v                        fresult += vec1[jj] * vec2[jj];3 c9 q/ \) C& m3 x+ `3 }
                }
. v" j7 n  g6 |- @" E- E% ~0 e                */5 E, W+ o+ u5 D: u/ A
                                
; G9 K0 @$ Z- ~2 ~. W' R                //Method - 3  N=100000 204s
4 c. b$ ~- w7 ^) `/ y0 Y0 O3 U- k                /*
+ ^9 H; t; O6 Z: q9 P                for (int jj = 0; jj < N; jj++)9 _: s7 c; N$ b8 q2 O, Z4 {& X
                {5 s- [' @2 `1 B5 g2 K" ?7 O2 i4 E
                        fresult += b1[jj] * b2[jj];. w: k; Q' W2 b. _% W3 q1 Q
                }
  k  k1 g% }% k% t( @                */
) l# H# ^) ~1 ?7 W5 ?* @5 p4 w! P, e0 Q  g! V
                //Method - 4   202s; y* t) E$ l/ {& I; g# x* N
                /*
+ o( I, a2 I- |6 [# ~                for (int jj = 0; jj < N; jj++)
# `& H( u+ }% n- Y                {
$ B) C' {! h7 _4 {, r. Q                        % ?1 O2 z: G4 F3 {
                }: {: X+ t% v, t
                */" k+ E+ M/ Y8 u0 |9 f
                //comment out all methods, N=100000  202s                ! A( N$ D' H+ O. g3 ^- ~  H* g) N
        }
! v5 d/ V# O" o0 x
; ?7 P  u" x+ H: |" e) D        delete []b1;
5 s" X. `  U! s% `+ @' W! L7 E        delete []b2;
) P1 i; b0 a$ v4 L  Y$ E4 n) Q3 X

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
4 B7 a% N1 |. X0 x% C$ D3 W0 ~+ w- K& v6 n& q9 b
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
  N9 [' a/ e* W1 c
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15' \4 f; Q6 q% c3 j2 H7 M# H6 {
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
- S+ U7 V: R: ~  s* r; c, v% H% \# x0 j+ z  s: c
你第二个试验里面的j在循环里面又重新定义 ...

6 p2 g& Y9 Q) S: }. ?内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) e+ r# o% ~  J

4 c7 i! K& L% k& v不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
8 P1 P2 z' o  l% ^+ s. c内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL% `- A! ~( h* h7 s5 u3 C) x# I' ~- ?

4 V  T  M2 }' `$ P不和它 ...

9 I$ C! i6 ^! j0 B% m( Y
5 x# o# v0 ^! w6 J$ Q' ?3 u9 W1 T不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
3 O* [, Q+ C, P8 E& t3 @后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
, Y- R' K! R# P; a. k1 ~, }- avoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* S' {2 E* X" f{
; `2 H$ g& R/ Y        comp temp, xtimesy;

3 N+ S' K! a$ m7 b" d8 X这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。0 X. F& y! \0 w! w+ M" z$ S1 b/ A
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?) P5 n7 W7 N9 ]& ]$ \1 n2 M, V
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
0 Q" _; o: Y/ H' S8 T  k! o/ F理了理思路,重新做了一个测试。
* M4 g9 d2 V; X1 A. G做了两个 vector 和 两个 float *, 都长 100000. |1 m0 X$ K, F! j$ v9 J' h8 H
外循环 6000,里面先做随 ...
+ C( |0 H8 S1 m: p/ v3 s& B; t
这个时间是从哪里开始算的?
7 \/ {6 `+ M7 G+ n  `& x我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。6 @- m1 u7 j7 T0 E9 ]4 B
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
' X% C! |) V9 K这个时间是从哪里开始算的?) N1 Q; E  u: n" d6 f
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
% |) K! s3 I7 X/ e
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
9 S3 N$ F# l# ?: O. E( N你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
& p1 n6 e7 H( K+ K8 W5 g$ o  U与此对应用数组(指针)花了2S8 N( X4 r% Z$ U+ o) t; c7 l/ ]
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54$ Q9 W8 ^6 b1 w: E  c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)! m7 U. D' I0 @, G
{
/ b2 Z4 }- e" S- D) F" h. [        comp temp, xtimesy;

6 g3 W8 F! e* Y; r我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗+ U. j8 k6 E8 s" e
. N, V. d; d, }9 Q5 K

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
4 w3 j+ b* l! l8 K" C我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
. S2 V% `  w3 [7 k0 H1 F' _* `. h  H$ P8 T
...
' F$ o# p' \" H/ [$ r
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
- m' Q+ d1 E, R0 @9 X( u0 N/ t0 J$ T* n
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ! ?2 N) k) j$ ?$ H; g& [, F

" e( g! v/ m! @  y) R是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。8 g: p. z6 d' V! ?
有空时我会试试 SIMD和并行,看看能提高多少。
" Z, E2 a4 s$ \1 @7 w  @" w过去7、8 年没有正经用C++ 写过东西,没有 sense 了
9 Q5 t& u1 t* u+ r( m: j/ @/ W谢谢大家的讨论,I learded a lot.  红包已发  & x, v3 K4 j' G" P" }- K

' ?5 h$ Q$ |" ~- a
8 Y  j; N. \8 h6 q5 ~0 F( v
* ]5 X+ M: S2 F7 y' C
8 v0 {% h7 d+ }, t  e




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