爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
. p- w* T6 g$ C4 H4 Z/ h9 A; e' y
1 `8 c6 S4 g; z& G' }$ Y* s自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
. Y& V1 `8 e; D2 m5 M% S
" j9 E) r( B1 O9 n0 S1 U. ~速度优化问题真的很有意思啊。2 R. k- C& R8 s4 I8 x
' q6 D% [/ h- ~6 x$ }* o6 ?+ a4 _
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?' @) }( R, D: Y* e+ M" l
把代码贴上来看看?/ c/ x$ x6 X# [" [9 U3 F+ l

8 Q: [. h% L: n6 ~7 ?难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 * I1 k# A: n) l* f' G& R
数值分析 发表于 2022-9-24 23:04
' F! P5 X) ], f' K( Z拉下来?拉多少?1 [$ m$ E7 j) y' i! d. [
把代码贴上来看看?
( e) G9 C5 \5 w+ P

, }  D9 K( X- Yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ f* _' b7 ?5 ~# ^
{
0 |5 }) C# I6 m2 E! u. m* `4 {! D        comp temp, xtimesy;1 j6 A. t% t% j- l& M
        xtimesy.re = 0;4 R% K+ k( V3 m  e) x
        xtimesy.im = 0;
- K0 Z0 p2 \; F7 ^4 l4 `1 Y        int j0 = lenB - 1;- t& C1 [* S5 n  N3 K& [7 H, w" e
        int    i, j, i1, reali;
, _! @5 `9 f5 E" _( E) H3 b" S        if (lenA % 2 == 1)% i2 R9 W6 o1 Y) ~" o: P2 q
                reali = lenA + 1;
# _# f9 |. @1 t1 c        else1 |' [) Y7 V. |+ d
                reali = lenA;6 T) K; f0 S5 o2 H+ }
        reali /= 2;
/ M( ^+ |* n' E+ w# a) B2 p& V* F6 V9 a1 E- s) `
        int nconv = reali + lenB;
7 k1 Y3 h8 f: V( \        //#pragma omp parallel for2 B# A- y/ N+ i6 y1 l6 v9 `5 e( A, j1 K
        for (i = reali; i < nconv; i++)
. {/ J+ j: a- \: d        {0 c) y( P" n+ m  B. J
                temp.re = 0;
% I" N+ a  d( f                temp.im = 0;: k& F' X/ ?$ R
                i1 = i;3 ?. D# K/ R7 t# B
                for (j = j0; j >= 0; j--)
# F( p$ W) J) B; K$ j                {. l' L6 h4 ~# {
                        /* floating date operation */
, S" M: M0 k, [& w* h" K- |                }

& N. ?3 K6 P; }) y( [( J5 h' X        }7 C7 V" j9 D$ ?: T6 M
}
' k6 Q$ \3 B, }6 J8 R6 V3 M) K# P
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
/ k& M/ P* R! m2 J7 R7 m6 {6 T9 a1 V6 p) I
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。2 m2 j4 h9 j2 {( x' W# F' Y
现在call xcorr 100次,耗时78s.- s% A* {; T( ^# k* ~
& W! D) w& ~7 M- y3 i' b" `8 F- \8 c
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
$ i( K: c2 L/ y
' ]0 ?% E% ]: g8 C' a
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33; \& I1 Y; z9 S: ?1 V- ?
Maybe Debug mode?

) o) A& O8 x3 Q7 c  f) X' o0 g% ~" d4 W+ N8 O5 M
不应该,看我上面的回复。
/ [: |; f7 r. k
( V. W$ v4 N( N$ @. e0 q我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 1 i$ P. W/ f& J& a6 t4 S% W
雷达 发表于 2022-9-24 23:54! q$ p& `' U$ c5 L5 t" L* Z4 l# x
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
1 u1 _" q3 m- ~- N+ {* i{) `0 Z2 j7 `; x  {
        comp temp, xtimesy;

1 C, L5 {* A* O( B
$ i8 Z% x2 u: w3 t0 ~( a( _这个不是这么比的吧。。。( e, p$ Y1 `( h. h5 q

' m& V& v. n+ V* o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
6 ?4 s9 h7 e/ E" e8 _& |4 O6 H" O: ?3 u9 N4 N, D9 t- H+ `- f, W! _+ Y
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
* R) N9 N$ l% J# S! F; w4 T: ]
数值分析 发表于 2022-9-25 00:20& y8 F3 [9 x0 N9 G7 r: N  c
这个不是这么比的吧。。。/ M& ^/ v+ B" ^$ Q% ^4 d6 K

* b4 x. q1 m7 v) K) Y9 ~: L/ L& [您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
  }+ K* u" {3 ?2 Q& U+ G) Q# ]3 q  r; `

1 q/ E$ g+ K4 c6 n3 p1 `% N有道理。
" }& W0 r' G% e0 `所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
: \2 W- M0 {: ^7 ?$ k) c3 J2 Z8 A/ O% l
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
! [, H. v# E: z. v/ ^, _有道理。. ^: V; C) A% z4 A
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
* A  M" @. P7 ?7 x
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多3 i( V) x  I7 R' m3 L
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:200 X* I; c: l% Y
这个不是这么比的吧。。。. O6 ]( f; N' A& H% n' A& U

1 I+ T5 d, _( Y6 @& d您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

8 U3 i- p8 h, Y! \
9 L1 A' G% k. y+ A. i现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 * m! [# q7 `# A9 ^/ E' Y1 K
沉宝 发表于 2022-9-25 01:480 _8 g2 }% e1 N* \. S& H# J
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
$ E  W! d8 A; d- N" J

, h. K/ n, u+ M3 ?是的,兄台说的对。  N) b9 _$ Q1 r% {

6 ~9 y* H, ?# u, j9 k; Y  q  q- j其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
: A$ k5 N$ o1 S  l( i, L
. V5 Q/ ?( w/ x1 q/ B2 r雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。: l) g1 A' }. E- a
* K) J  G( F+ \. ^; w4 k3 y6 U
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。3 V, S/ M7 g  Z, x
7 O1 E/ ?" v2 d, Q1 g! T
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 3 F8 ?2 P5 @8 {3 W6 t6 B7 B) c) G
沉宝 发表于 2022-9-25 01:27. g: n' Q' R2 ^8 Q$ w
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
: N/ ?! m/ e; C
" }: s* y) _  N+ u0 t6 B
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
6 Y5 W# F+ X( @6 c/ y
4 ~& V) d% L3 i8 O, `; c我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
9 i9 |$ ?+ r. H5 `9 x$ y9 [% _又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

5 T4 s. {# U) `- ?时间差一倍的结果可以接受。
1 V1 o8 M* I$ i
# ~, {3 J7 [8 g+ c你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
3 I3 z) z- }) [! k; X" p0 k
雷达 发表于 2022-9-25 04:47
- q7 {6 W4 a$ f" \- l1 S" ^又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

# f! Z; b/ j. }/ ?; ^: K0 h  h5 M  X, E# P$ M) U( p
% Z5 [( \# d7 z0 X* I# A% _& {
- e  O" q7 h0 ?  w% @
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
. T0 C5 v* r, V. R
数值分析 发表于 2022-9-25 14:58
: N2 R7 j9 M+ c7 Z2 @& b能不能把这个也贴上来,看看和上一个有什么不同?
3 P: N4 o9 Z/ m4 W0 i8 n- Q/ }
理了理思路,重新做了一个测试。
) S3 w9 |) ]) k7 g0 t9 O做了两个 vector 和 两个 float *, 都长 100000
2 n9 ?6 W0 \3 }* Z外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.! C8 ~* B$ G2 d  H4 T
9 ]& b0 F1 C: X# {6 Y
内循环试了4种方法,
9 B: K' i( m* k* D* N) q1. 直接调用 vector inner_product 247s
; H# n3 g# a' q" O, a& O8 u2. vector 循环点乘累加 237s
! k! w& W% ?) L0 S5 D5 l3. float * 循环点乘累加 204s
! D) y# o0 |  y- E# Z4. 空循环 100000 次 202s) L8 u. B* g5 c5 w  S# {

9 }2 v" I) u, w- L( a5 c不做内循环 200s
3 C  l9 O& f, L$ i- }0 o5 G; g7 V7 W0 t
你昨天说的对,内循环本身占比是很小的,大头在其他处理。: b* @9 r* ^+ Z- J, c4 i+ P
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。# I3 a- ~- H1 K" S( k* f6 k0 z# H

* J' C6 e. Q& Y( l% y  u5 _- w" Q6 w6 \至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
  A5 l1 a) T9 C% o- d5 i
6 C" b0 W% c# _$ q& t' _(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
- X+ }2 Z/ Y, A6 s+ M* Q1 z2 B3 _% m( w+ P
        std::vector < float > vec1(N);
( X9 K; t4 X! O0 m3 D" p- R6 U        std::vector < float > vec2(N);6 x  {; Y, J2 s& Q$ [
        float* b1 = new float[N];: V  n6 }( }$ j& R% ^6 P
        float* b2 = new float[N];
6 p. v  v; R* l2 j: R0 W) I
( d# P& G; |# l6 v        for (int j = 0; j < 6000; j++)  I) y: A' `1 t7 X7 L5 t
        {
# P# u! E1 u8 T! p* o                std::generate(vec1.begin(), vec1.end(), []() {
/ [; p: N6 L0 _6 c* ]                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;* f0 Z# P3 j: R5 _% h
                        });
- E8 |9 r- ?0 l. b7 @8 ~: w$ f9 u4 n6 A  I  ^" h( p
                std::generate(vec2.begin(), vec2.end(), []() {
" H$ {8 t/ U0 g0 ^5 e- n+ o                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
; ^6 z# `1 J. F5 S6 d7 I5 L3 D# J                        });
7 H( j& Y4 q! }9 N, }( L$ e# K, x9 ?/ c( s- M) H0 I
                for (size_t jj = 0; jj < vec1.size(); jj++)& x/ D* N) G4 a" d1 G
                {+ w: g% O! O. V2 d& u: |
                        b1[jj] = vec1[jj];
* _( v. B  y, U" ^8 ?+ B- n6 z                }
' t# W" T0 @1 R3 C* }( H
2 k8 |: a. U. M: o% g, b6 Z                for (size_t jj = 0; jj < vec2.size(); jj++)- e& l7 b1 c4 P8 e4 b. ^4 C
                {
0 r, g9 l5 A; d) B4 c; F# Z                        b2[jj] = vec2[jj];
9 k- O& \6 ~! }7 o                }
& x* O% O' Q) N9 Q+ i) y6 F% j) c: r5 g4 Q
                //Method - 1  N=100000 247s  ! `% L- T$ e7 X. j! }0 a
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);& o0 L7 B7 W. p7 A
                                % [; y( w( A, H8 ]- ?9 g8 b
                //Method - 2  N=100000  237s2 G0 a; D( B" J% W8 [
                /*
/ ^0 ?- g2 w  t  @- g+ Z1 h                for (int jj = 0; jj < N ; jj++)
& M# t1 [: m9 U  C. d  n3 Z                {
# i2 g1 e- s6 I                        fresult += vec1[jj] * vec2[jj];8 ]* e& H9 l' f; S3 o
                }
. a9 _% `6 Q9 l* A6 ?" K5 z                */
+ ^: ^1 D/ J: `4 x) g. P                                
! z" R- I& ^4 z3 b9 [# P                //Method - 3  N=100000 204s. \% H4 d! j0 }' k6 u2 m- Q" S9 P/ V
                /*9 t+ s3 b5 c3 C
                for (int jj = 0; jj < N; jj++)
/ {* e8 X- B! l9 R* i) D1 }                {, r& n! p* a+ r: k5 K- L& Y
                        fresult += b1[jj] * b2[jj];  E! I* l: C9 ?3 `% K$ l
                }
4 q+ X+ ~9 @9 f; Z                */4 m/ ]2 A$ ^, A5 T4 `

1 ^: f, c( s4 @9 X) S% L                //Method - 4   202s' S* c% P* m; ]0 G
                /*
* ]+ R: W) v' I& F7 o2 j$ X                for (int jj = 0; jj < N; jj++)
# g0 O6 y- L/ ?: t: m; _6 K: a                {
/ a& I) @7 k' a0 G0 E                        
' T, `5 H+ h& c' e                }6 L& Y; D6 R: \) X
                */  E% n" y( {. S, i0 f, I. D
                //comment out all methods, N=100000  202s                + p" f! X) R- P4 G* G
        }* B. M7 G9 b6 ^. r8 y

) K9 N7 [9 J" _; J  A- L        delete []b1;3 A  ~2 \- _0 g5 c& C
        delete []b2;
- o1 v* V# @' z5 Z% e, I6 O! ]

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' N0 t6 L& h  b) [$ E' q
& G1 e" e! H+ ]& B- B9 Z你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
- w7 d4 u/ R( `' P- i6 m  A
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:154 r' d9 n+ x! C8 S2 @
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?# i. U; ]. |+ o- F0 i
9 i  z3 V' r" a. Z0 X8 R
你第二个试验里面的j在循环里面又重新定义 ...

8 a3 F, B- ^& K- Z4 g- v内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL0 |* B: |1 D# ?+ q" i0 P
. _  p: M! r1 f9 b* I8 i2 X
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16* m( ^$ f8 D3 j9 x$ X( T
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
2 J7 A+ A  z. m0 O/ |) a, e1 Z% V$ b/ y. d
不和它 ...
0 t' M/ c5 S& y0 Y: g" @- m

4 w7 N+ }0 [+ D7 P不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。6 I3 P+ i1 w/ s$ o5 a( t
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:547 n8 m' P5 `3 K+ D  {1 g- s
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ a' P$ t& T: m8 A6 r5 `# }{
% e( K' T% x7 ?        comp temp, xtimesy;

& }' q4 D' [5 ^/ G: t, a5 e% R这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
2 }2 ]6 A' \2 \4 N. N; D. u( \内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?7 j7 \; g# N* ?6 A  t+ U- [' E/ B8 D8 t
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
6 u1 i- X4 |  s; {* ]! y理了理思路,重新做了一个测试。8 U1 g* {) c1 g' t- n& N
做了两个 vector 和 两个 float *, 都长 1000005 g/ H8 v0 I. N+ I! E/ G
外循环 6000,里面先做随 ...

! Z; Q& Z! g- B9 B: b这个时间是从哪里开始算的?  A  L0 K, n. }+ f8 E# @
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。& D0 ~: @, y, j0 a2 ?
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39# b: F6 a2 b# R: P
这个时间是从哪里开始算的?7 c' S& I2 i) R/ S/ q2 g2 `6 g
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

+ X! D4 I/ S4 f( T$ F" G: I' J我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
5 u- ~7 G4 n: F你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。0 B- i. j: P6 z6 P# z8 F+ @2 R
与此对应用数组(指针)花了2S$ l- f! z  o+ O: D) X
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54* G9 I3 R/ U, F8 c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)5 ]& M. M% |; ^6 X
{
+ ^  S  O( l+ K1 A        comp temp, xtimesy;
+ d% u$ K5 Y5 `% q; c8 a
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
: X5 a: B1 D' l: c7 s  a3 O
4 \' J. z( A. l6 u: O
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
' h7 z2 L4 ?# {/ a我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗0 [1 c+ g( p- D! `, q* a; h1 ]
( l9 X( Q3 K' Q  f
...
# Z. y! a+ V  i
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。8 U, {' \  a( g" }- F+ V  v
* d2 i) l7 v& F1 f5 z6 y# H. D# j7 k2 t
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 - B% s$ O2 r* }2 h1 i) _
; o7 ]& h  _' s5 _
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。* j# Q. h& j( j( T5 O4 v
有空时我会试试 SIMD和并行,看看能提高多少。" x- U, m5 L: r. ^! Z
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
3 T  }' h) G  }, C  s' A) b7 z4 b6 F/ x; m谢谢大家的讨论,I learded a lot.  红包已发  & p% b0 a$ k1 O0 g0 q

/ z* @% O1 ~7 E0 j( I5 z" S- p
. q9 y3 X0 U' Y  u& H1 m, Q% o) `8 C/ n. @

: @' [9 B  P# L




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