爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?! g; T4 D6 Y) F/ N+ L

/ a6 r7 w( _; u# n$ D7 [) E2 S自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。% Y& p  }" R2 I7 x  ?

! M- J- z! l0 c0 r; [速度优化问题真的很有意思啊。/ p; p9 c) x* G1 q$ R5 f. X9 f/ @2 a6 x

6 w* O3 q1 j( i欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?! @" G8 t5 o4 w( ~, b& @/ B
把代码贴上来看看?
5 q$ _; _$ k; ^) a0 \6 g& N% u+ l2 u* M; Q6 H) S  n  O
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 3 Z1 B4 p# U# d) D0 Y% c
数值分析 发表于 2022-9-24 23:04
7 v+ g* u& T( y$ e4 h# Y& m拉下来?拉多少?
0 Y7 q# N9 i+ N) r7 C% _. b5 Y2 q把代码贴上来看看?
( H; J' r$ b' I

9 E3 _2 \( t" Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 g1 }2 a8 `5 B* T{- n% K) M! b( G8 K9 W; D
        comp temp, xtimesy;
7 _+ S$ J5 c4 ~0 x1 p3 K        xtimesy.re = 0;! d9 v( N$ T- ^' f0 ~1 z
        xtimesy.im = 0;5 w, v+ {& P4 a+ n" e
        int j0 = lenB - 1;) C, S' ^. M: u- @0 E; A
        int    i, j, i1, reali;" z5 D. o) \+ P2 H
        if (lenA % 2 == 1)( b% I4 K/ X8 O& R. F9 f/ ~+ v
                reali = lenA + 1;' x( l" k( k4 g% ?( ~( ]+ z* U
        else9 j$ o% U, j  I3 {" |. b
                reali = lenA;' h8 S" M8 c: t3 p) v9 v* }
        reali /= 2;
5 h6 D* r# P( V* Y* N3 p' R; x, t5 f# v1 l  l: j/ ^6 l: o
        int nconv = reali + lenB;3 o! a$ C( [" k) c6 W* v1 F! _$ X) T
        //#pragma omp parallel for+ V' F' z8 q- j1 n: r8 ?( u
        for (i = reali; i < nconv; i++)5 V% x0 x: ?( G8 y: ?/ K7 L
        {( t0 E" `4 Y# e1 a8 w. c
                temp.re = 0;
' V: C! J* ?$ Y! i& H                temp.im = 0;
( R2 D4 _" p& f( G4 X* I9 U# r0 }                i1 = i;
* E" c8 ?4 L2 m  [3 y) A# R                for (j = j0; j >= 0; j--)
* c: t. H0 M; I8 @9 ~+ l6 R                {
/ T3 ]3 c+ q, R7 B                        /* floating date operation */
5 z; F* l7 N2 t  K                }

! z7 A$ j0 l7 t: p3 P! \2 R        }
1 Y3 j+ H# M3 M; G' `2 @$ y4 U}* \* w# @4 B8 b+ T
( r" _; W. a4 w' |! b" `& K
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
1 C# F3 B* |' F9 j
. @5 s0 t/ o' y0 |红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。: s2 j; l- r3 A9 Q) C6 Q+ [6 C
现在call xcorr 100次,耗时78s." r* K  p8 A; i% i

( ]6 d5 k4 L2 Y如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. : n- d) P% x, k6 z4 d
2 i/ V3 R& q& S- E! `

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33" i* \& K" }  W  T) D2 |; q% q- M
Maybe Debug mode?

. s+ k" ~  g7 ~3 k" V2 x% R9 p/ E4 S5 I  J5 B! F7 s  @
不应该,看我上面的回复。  Y5 b0 u, m/ x- _
" b* L5 x: `  w6 Q9 G/ i" c
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
$ Q: M- z& f0 k$ r
雷达 发表于 2022-9-24 23:54
. b) t5 w/ p  [" |# t0 G* ]1 jvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
/ C8 `# H0 e3 f4 R& {+ R9 y6 z0 S9 ~( T* ^{3 {7 X9 i- `% z, J3 i
        comp temp, xtimesy;
3 x5 L9 {0 u: H* X% `4 K

5 a  O8 Y! _& C2 l$ i4 _这个不是这么比的吧。。。. h. F# X8 V' i6 u+ Y1 D

2 N+ Z1 C  _7 u/ |您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。; M/ a  j$ Z5 e
* L) u$ ~6 S6 p5 p5 L5 g8 r
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
) x: l0 ~6 B: I. l
数值分析 发表于 2022-9-25 00:20
4 A+ \/ ~+ a1 k7 r# p2 T# j这个不是这么比的吧。。。& g: i+ A3 T2 I' U8 i

3 I2 M4 C9 E' S# w/ L6 X# |: L您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
) M) ~* d* T8 I/ b4 v

/ r: j3 L" w" ~2 Z* _% S  F有道理。6 {% o$ h# x6 _
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。! A0 S2 c# Q/ F

' L  r  n; S" j) C$ d9 C. v: k' I我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:462 p" o4 P2 ^) |) b( V# a
有道理。  C4 ]- u, k2 u5 ]& Z
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
3 o( v5 p4 P3 h# O( v5 {
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
: [1 {! P; A0 {9 j6 Y# {Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:201 k( o" a" g) _0 l' y% B6 ?3 o
这个不是这么比的吧。。。
* @/ H7 X4 z6 I
$ U0 ]; n. q  Q/ V. \* B您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

4 w& t. Y2 H& {; l! |! T. q: B+ G7 h
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
% O1 k, i9 E3 _( u  a# c! y- C3 E
沉宝 发表于 2022-9-25 01:48! P- t5 |8 x  T  P) M$ D
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

$ _1 V# q& f8 ?7 ?+ D0 k. T0 U
& ?; Z4 o! B5 D  g6 j, o是的,兄台说的对。" c3 z) W$ d( M! {: c2 ?* @3 R
. o7 k9 g& g  W: x
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
- E& x5 x$ M0 Y2 P1 [, M
, s4 Y) P6 p; L雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
8 q7 T& l3 d5 c4 R0 r# B1 G9 J8 S9 s% g- A; E! d
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。- t7 M* o8 L: m0 a4 r( o4 ?

- w! x$ j! V8 M# r6 `当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
9 z1 h2 w% H5 I% D, G4 X
沉宝 发表于 2022-9-25 01:27
$ M4 S; w4 M0 f! Z: ]  F你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

1 t- W, P! r) {9 r
2 X$ V' A" I+ M7 L0 n. z( T6 c# l又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。$ d& f( F& F- P1 f( ]8 g
5 a: b2 h9 U3 V9 W/ P( j; B3 `
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
# R7 k+ c. n9 C5 e又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
1 C* b7 x; C" H* \4 D/ s4 R8 H& r
时间差一倍的结果可以接受。# L9 t( p0 b' M" R' ]7 ~5 \

& }& W8 Z. i, c7 _( e5 n$ f! u你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
- r& M) @! v4 `8 }
雷达 发表于 2022-9-25 04:47
# U  i$ z' O) j又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

8 r2 @. u1 V4 g# r* j! h; @+ I) }. p3 P: u. \

2 J8 V8 @0 U2 S! C  [
; @4 U3 r. `4 `2 C5 m( S1 n" n3 b; T能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
, d% R( G* K* t. M+ l
数值分析 发表于 2022-9-25 14:58
- H! K0 c" ~3 n能不能把这个也贴上来,看看和上一个有什么不同?

* K0 v7 v& {8 Q) k' K0 b, w+ u8 ~理了理思路,重新做了一个测试。9 b) T& w  d7 T6 a( Y7 q
做了两个 vector 和 两个 float *, 都长 1000007 H# s" p7 d; E% d
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! j. S2 v3 S& _' ~! e1 L
- F( Y9 }5 i, t1 q0 v  B内循环试了4种方法,' T" k) x0 V6 C5 Y& \9 t6 ~
1. 直接调用 vector inner_product 247s
, H3 {; X1 |: L) R9 ~4 w4 R5 Z2. vector 循环点乘累加 237s
4 C: B3 G, n: ]4 d' P3. float * 循环点乘累加 204s7 ~# Z1 |2 I: y
4. 空循环 100000 次 202s7 m. h& p% \% D: u

( `+ V: }! n/ l不做内循环 200s, U) Q6 m9 K: y9 `
8 U" W" [1 T0 a
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
4 j) K! P/ b( Q另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
! x0 k" i2 a( w7 r5 x/ _6 e$ s9 |) [
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)# L; h, z8 Q( c4 I( T4 e" _
& N: w4 X3 J6 O- q
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
) U# T3 d4 ]( O# y4 Y, Z
4 |( M: f' I' }
        std::vector < float > vec1(N);
) c( D3 Q4 ]- s        std::vector < float > vec2(N);
: L' A& L$ Z1 v3 W: t: S        float* b1 = new float[N];5 Z5 ^( w& a; ]* P! ~$ E3 `( Y) K$ v
        float* b2 = new float[N];
7 E4 q. h0 X- f. Y. a+ W& w* z: R
        for (int j = 0; j < 6000; j++)
: n: j1 q& i; ~/ s+ t( b! y8 v$ r        {* C+ B& y- q$ ~8 Q: r. y
                std::generate(vec1.begin(), vec1.end(), []() {
- M; R% p( m$ k! C8 K                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
( ~. `: L$ W% v- D4 }( D7 n                        });1 f# I0 u" R/ J2 B6 p
* x! s9 U& H* z
                std::generate(vec2.begin(), vec2.end(), []() {
. b) e3 g, R9 j/ B# O/ p8 `                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;( v, \2 [; U  H4 ]# w& R9 i% o8 D
                        });' q7 y" [* d6 G: c$ S

! s% {# `3 h; W" J                for (size_t jj = 0; jj < vec1.size(); jj++)
# O7 I$ V( J& h9 s; I) E$ t                {
7 _( S; w  k& o+ F, g' C* \/ w                        b1[jj] = vec1[jj];6 y$ U" f: G4 c
                }
- P7 S. Q3 G) X& s0 h! P2 i. v% U6 p# d4 Y3 `
                for (size_t jj = 0; jj < vec2.size(); jj++)
$ Z0 e6 e0 n% C  p                {2 m" U$ {. v( A! l" D9 k
                        b2[jj] = vec2[jj];; b& C& g9 v0 e- s$ E0 Z+ ~! R: D
                }
' q! s" |- z8 k, p# X. b
* x. H1 i0 w: X: R                //Method - 1  N=100000 247s  " N1 k: l& Z1 g! n+ g
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
! q% X. m! ?, Z4 }, m/ r* i                                ) r9 ?9 N4 Z$ L
                //Method - 2  N=100000  237s* j! p3 |2 q0 [2 t) z7 s
                /*; p* |/ {+ p1 r( I8 i( Y$ u
                for (int jj = 0; jj < N ; jj++)3 v+ [% t8 z- @: n, C3 p
                {
- @1 K$ V& Y# M8 p8 l- T                        fresult += vec1[jj] * vec2[jj];
( E: @) j3 u6 j4 Q& Q1 M                }
  ?' F; H+ t% \6 i: l7 n" c8 m                */% u1 Y: a! F, C& }5 X
                                
& M9 j8 e% y6 f                //Method - 3  N=100000 204s: D: U' p. {/ R: Z4 C" N
                /*
' R* N. i" z1 h$ {                for (int jj = 0; jj < N; jj++)
% l& B1 u( S% ]% A, _" q                {  ]: B$ q. B9 f# X8 N8 R
                        fresult += b1[jj] * b2[jj];
* [7 _8 @( _. w! m8 U3 l                }
+ e9 H! e" I8 \! s1 Z. n' \                */5 [& _( `: w9 t" s' c6 Z1 v: C" y

! I. i& M0 i; P. t9 w                //Method - 4   202s" k! |% O" @* @5 o
                /*
& _. A, D! `9 v+ k8 p. q; C                for (int jj = 0; jj < N; jj++)" E# D, c2 d7 M1 t" k
                {
" K$ v) n# Y& w2 R" X+ Y; F                        
. a0 O! k5 S7 D6 c( k4 |8 E2 }' p& E* T                }. U' r+ t5 U% i& Y4 D& v
                */6 g! e( ~" J' g. u
                //comment out all methods, N=100000  202s                ) g! b% k+ y' k. x$ Z- R3 t
        }
6 K. ^8 B* x# n( T8 ?. D8 p. J+ Z' Q' \, Z  [/ I; S
        delete []b1;" J6 d, x$ k7 G: E# i  v& l
        delete []b2;
$ B& C5 y& E9 q. U! f& u

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?! s! h+ j; C% r, o8 Y, B1 ]
) i* \! F3 A/ i$ E) P7 N% K5 o7 i. M3 f
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?. ^+ C5 S- }1 L7 o

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15  E9 x$ K. t4 q  q9 {
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?1 e2 v" u2 J+ {
) B, u8 g) K+ @8 t1 J7 z
你第二个试验里面的j在循环里面又重新定义 ...
% N$ L3 ~$ {; @$ q' D% Y
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
, j( U5 W. M  @$ o3 ?+ \
+ k; B# o8 d. Q9 h2 ~9 Y不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
( u  H+ _# p4 u内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL7 \- Q$ D) d, e8 B! _6 v! U, T
, x) f) R6 K; L3 O# _# F
不和它 ...

" K/ l( L  c4 r4 X6 A- u. ^$ b2 X8 F: y' `3 [3 C$ M( b) f" [. [
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。, K: ]# }% _8 Z, k; Y4 i0 o; N
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:548 L" w+ u: N0 J$ L. }# |/ {! w
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)& ^4 ~6 L( A7 k3 C$ \5 T
{
- A& j& ~% p7 Z5 x8 a: l# B  W        comp temp, xtimesy;
1 Y; G( x3 J- j( z# b
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。) A+ z: K! q/ J4 d9 O6 R
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?( p8 e) `# [1 j* X- f! ?
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
$ Y" E1 k( V5 c( g9 B/ v8 u8 u理了理思路,重新做了一个测试。
3 s9 Y. x5 X- A! h6 T做了两个 vector 和 两个 float *, 都长 100000
$ m$ B/ B' K0 o2 O% L0 F" \外循环 6000,里面先做随 ...

# j3 b; U6 l5 w; T1 ]& H这个时间是从哪里开始算的?6 G% C/ ^# f: t2 y
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
3 _6 O6 R: V6 F. W( a按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
8 G. t/ t$ ^' T* _5 M0 q这个时间是从哪里开始算的?. e( h. X- V( ^( R: ~6 b
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

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

3 ~. D5 _: P, ]  L# u9 ^
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
" j$ S" R. a( j; s7 ?& G5 p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
* A, ^3 V6 A( f) ^& T' D6 |6 ]1 m4 m: e9 {0 L
...
6 _- i8 ~% r) s, h  N  l, [
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
* F. \. S/ c/ v6 ?7 u( ]$ ?7 y' f: J' v
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 4 [1 E& ~% f6 D4 v, }! I/ x) b% F

- |# d5 W. Z4 ~$ I, S是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。4 L2 S) n1 H  K+ t5 ]
有空时我会试试 SIMD和并行,看看能提高多少。- a, y+ H* P% ~
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
( |6 ?5 h- P( _1 \6 ^  A, M谢谢大家的讨论,I learded a lot.  红包已发  
3 f$ i. Q! R6 e2 e1 q1 Y
  l5 B$ g6 |* f1 {1 m$ u8 m' w7 q& h4 H# J

- `- C3 q. q0 S) l+ Z4 y$ H3 I/ j' o) M5 [% c





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