爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?* B: r! b) ~) i% t+ Q) G0 p

8 w: o- n' @) T  {* u  c- v1 B% o7 x自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
! Q( q, ?( N8 w# K/ |  D* {/ k2 M( ]2 t$ ?8 p
速度优化问题真的很有意思啊。
* ]( J; {8 Z+ M  |0 r* ~2 g
0 _  y- U% o" j8 j, b欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?5 [: N9 y! H$ N! V0 D
把代码贴上来看看?
; e8 i5 w! ]6 U4 y9 d2 x- u  t+ _
; N3 h) l( I' t  \难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 0 D9 M2 Z" b& e; N( p- y9 G' A: y  y
数值分析 发表于 2022-9-24 23:04
$ N: `( D% R; k3 n0 o, W" |拉下来?拉多少?
7 p/ V5 ]! d' g& q" s: Z把代码贴上来看看?
4 h$ e5 g7 m7 m7 m2 W9 t1 ]

8 U$ }- O. J2 R6 cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ _8 l" ?  A, k4 b: L0 G4 O% _{
5 ^6 H9 d& J8 r- }- N2 c5 \' ^        comp temp, xtimesy;
  `' `, Z0 t4 Y7 m; P        xtimesy.re = 0;
7 x, k3 Z  \: ?        xtimesy.im = 0;7 }6 K9 u1 @$ j7 H
        int j0 = lenB - 1;4 k6 p! G& v2 D' o  Z
        int    i, j, i1, reali;' y, M: T* l1 j
        if (lenA % 2 == 1)1 B3 b: G- U& E1 B1 p. ~# T- c
                reali = lenA + 1;
+ y$ Q2 F3 I# N( e# [4 i# J0 @        else/ f# r0 k* ^8 u! U& N. w. k$ F
                reali = lenA;
$ n& l: _, g2 g        reali /= 2;
4 w* D- I4 ]. T% y& `- m8 w2 m4 W  _7 G
        int nconv = reali + lenB;$ ?( }" t! S1 Z
        //#pragma omp parallel for. O4 D$ t0 E. J: E
        for (i = reali; i < nconv; i++)3 d% A- Q: T0 ]5 R
        {
0 Q' H! u' ?& ^                temp.re = 0;5 C' J# ^# G7 l3 ?
                temp.im = 0;4 P' L0 o0 t2 Z9 @: M) M) _1 |! r
                i1 = i;% S9 y3 w3 p4 v/ }) a- @
                for (j = j0; j >= 0; j--)
6 H5 M1 O2 f+ g) ?( T, J) j5 s$ {                {- i3 M0 ?; v! p( p
                        /* floating date operation */
" l& d$ ]. G+ Q% A, O                }

( b& P: n# r' t# A+ ]7 j: a  [        }5 R% d4 {" R! H. F8 L0 ?" e( C
}% s' O% d7 U# b! G% {3 h3 a- z

* k, Y( v4 ^! P6 a; V* G, r3 wxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样- Z( j3 p) X' Y8 y
  @" k+ x8 ~5 G1 p& B5 D0 v4 x! k
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
7 @( t! H: P9 @5 u现在call xcorr 100次,耗时78s.) G4 }0 ~" [* w2 O0 r" o' U* x$ r

( Q. i2 \/ D5 U+ v5 O2 m/ R如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
# E! G- b4 m- I: v( B2 X4 ]* ~; z3 C/ H; h* l9 ]

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:330 Y9 b) L5 P/ b* Q
Maybe Debug mode?

5 e$ m4 u' y+ Z7 x2 m) s! H
+ t) x% h  n, n2 O% l不应该,看我上面的回复。7 D: Y. l, ?3 P  V" B9 R6 ?
6 B6 M, f  S+ J% _1 h, D
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 3 R9 ~4 Z7 ~7 L3 S3 N2 ~0 q
雷达 发表于 2022-9-24 23:54
6 z8 K( P6 R7 W# h& H$ ]$ mvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 }- o. A( a. D. {1 U" J' {
{
/ u+ v* X0 b, I% C5 |        comp temp, xtimesy;

7 @5 _$ y, q( H" ~7 v& H7 o
! F0 s% N. }, b7 }& S这个不是这么比的吧。。。# ~/ g7 A, d% k7 k0 D4 p
& l, V/ X1 f. U
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
- a) c1 h$ `+ t
; A( f% j3 k7 W  \& X/ w而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 ) ]" [( W6 U0 s# m' r
数值分析 发表于 2022-9-25 00:20+ l9 _4 C( e! o* D# v1 h
这个不是这么比的吧。。。4 }/ r' ~. C: L" J
: {( Z& k, O* R+ g+ u
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

6 R- }. V! W  \3 k6 _* l3 [2 A% b) \, m9 }  b
有道理。
" V% N3 y& Z7 e1 M3 s$ L所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
* o/ M* y" Y0 c% S" t/ a4 i' s1 k6 {7 l+ F5 X8 \
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
+ U4 a' h7 `# s8 l; Q0 L' R+ {0 q有道理。
( X. w% C' |: [( I' j6 l0 v所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
' W6 m  f0 Y  m/ \' }/ A4 k6 r- e
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多% t; {( `" Q6 t: }8 j
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:206 B3 g: R$ L+ ]
这个不是这么比的吧。。。
3 g! D  p+ b6 B
* P- _3 u$ J' I您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

7 a2 [, l. ?* T2 F0 u9 O1 ^; m# E: Y3 u$ n0 l1 l
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
5 W% \+ z. j- [0 `: P- M; A
沉宝 发表于 2022-9-25 01:488 z* b& x! X* p
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

# k# K) U" l3 H7 ?3 }4 ^/ X8 X
是的,兄台说的对。& k6 k. d5 I0 G0 D& ]* Q' a/ `& x

$ y" l/ Y4 y$ l# R0 t其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
" l% }. p) k* q4 v/ F, ^- s. W9 Q- c9 Y, e/ Z  o4 v7 t
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。) Q/ x& D6 W8 I+ ^7 I4 }: n

! X( [+ B/ R) E4 r; y# A, t% {比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。+ M# O8 y  U; O6 S9 p
) }+ y" o2 C0 M7 R6 o5 a
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
6 [$ s7 r- V( i7 K4 G% B. I
沉宝 发表于 2022-9-25 01:27  a3 p+ G; g" j6 _; r! J
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

: }1 M! W! ^( X0 m. b; F9 m6 U4 Q
6 P$ Y: S+ ^. K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。  M' I- A! ]5 Q" [: `4 y

$ r# z0 C5 I6 K% E( b. x$ B) a& _! n我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47& q% `6 T6 J* \; J
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

5 i8 D' b9 n" [1 P. g9 Y# k时间差一倍的结果可以接受。
* p) q; G9 R- t5 P  @- h
  |8 p# z& ?' m  w你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
: e1 W: P) A3 K( z+ c6 L- C
雷达 发表于 2022-9-25 04:47# _( u, b! y9 n( h6 y; K6 g9 T
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

. L( n* b, A9 V. w! ]& }& G) o  S  y/ f) H) |

) k' g1 q9 Y9 t0 j# g' d6 F- K# C! z6 a
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑   Y* n  V4 F/ K
数值分析 发表于 2022-9-25 14:58- E( ]# R; ?7 Y: M
能不能把这个也贴上来,看看和上一个有什么不同?

4 ]( d; t, f& c3 L; _理了理思路,重新做了一个测试。
: O) {, }+ ?; E; g2 A) z0 ~  a1 h做了两个 vector 和 两个 float *, 都长 1000005 b* v# ?6 R6 ]; Z& I; ~
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache., v3 _; |2 p. `8 Y$ Z! Q& N
* \8 {, G: U& A4 z1 u( `
内循环试了4种方法,) Z1 P7 {5 e+ _& R
1. 直接调用 vector inner_product 247s ( h7 C% V; N9 B8 r, L: C
2. vector 循环点乘累加 237s6 E5 C5 f" s3 U3 o4 @1 A2 L
3. float * 循环点乘累加 204s
  O: O1 }1 O0 t/ q4. 空循环 100000 次 202s
: J4 m! S5 I( m1 B7 D# a- L9 k
  K! C, Y0 [) g' x* e不做内循环 200s( P: o3 J% w; g8 j* J6 ~
1 W& R/ j# B& B+ ~
你昨天说的对,内循环本身占比是很小的,大头在其他处理。/ r. B) k) w" C6 |
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
, @, c3 k' g: [4 l, P% T  w' u. G" G$ H* M# R
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
" v; R8 E0 T0 I" w; i' n/ w4 g( q$ q" [
. d% F" y: C+ @% N& w+ j(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)  K1 V+ n1 R  Z
, t3 ?2 f, v7 n3 ~, s' A
        std::vector < float > vec1(N);
) j) w' x+ j4 m. {/ ~        std::vector < float > vec2(N);
5 @9 n  q. _& d9 }5 z; ~( Z        float* b1 = new float[N];
6 A9 ?; O. w1 T8 {4 ]' E, a        float* b2 = new float[N];
6 O! ^$ n" j, [! z& S. C& u
) V& Y( V* H, Y( k$ \( P        for (int j = 0; j < 6000; j++)6 m5 O) F: `( o9 Y1 K$ I
        {( E5 v7 K& N/ z
                std::generate(vec1.begin(), vec1.end(), []() {) x) }5 D, f+ S: H5 V. [
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;% i+ l' Y& H( ?2 D* W$ e( E
                        });; L! R$ j+ a& d7 l

; o& k" U: R  r                std::generate(vec2.begin(), vec2.end(), []() {, I- Z% Z; V. _7 g, T8 ^
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;: R+ R2 B# e9 [0 I) Z, f
                        });: O- o* L/ `& t  q$ K. H
1 N. E( ^5 v& e- E1 z" V0 S; e1 i
                for (size_t jj = 0; jj < vec1.size(); jj++)
  ]+ V9 [: G" h% J9 f( n: s                {9 L1 Q: D* H$ u
                        b1[jj] = vec1[jj];4 `* p) @* G8 C  Y# w  `
                }9 @0 G" J/ a! k" _' h( l7 A

6 s0 q' L9 G; P! G: ^) s                for (size_t jj = 0; jj < vec2.size(); jj++)
9 r; v! u" {6 ]) Q% Q# v                {
& W7 x9 T4 t( X  m- v- u, T                        b2[jj] = vec2[jj];
  x' R" r. A. R4 B- r                }
- z5 l9 A4 ^8 a, z! E: C
/ H7 m: g- c- I: s# W. G                //Method - 1  N=100000 247s  
4 o% ~+ Q2 t2 B" |& B) C; M                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
6 J! I9 C$ k% B3 h$ {8 o: O                                
, Z3 Q  J) |6 t  U0 a* ~  p; i                //Method - 2  N=100000  237s
( K8 h; u8 L/ x( n2 H1 ~% |                /*
* U3 O; r$ J* E3 L. b                for (int jj = 0; jj < N ; jj++)" J) c, U2 }8 K( f, v2 p
                {
# ~& W& [- o7 T2 @$ ^+ H1 b                        fresult += vec1[jj] * vec2[jj];2 e) R0 w9 v, c2 I: u4 H9 f9 C
                }
' |0 _0 l! L/ q4 B; X! y8 P                */
9 q2 z  C  I" Q                                
0 e7 W5 _) f; E  q7 b" \' t                //Method - 3  N=100000 204s: j9 C1 Q! _8 C3 x  t
                /*# D6 G2 u$ \% W4 G% @0 {
                for (int jj = 0; jj < N; jj++)! o3 _' y/ t: ~) E' X( j
                {
  I/ b/ Z' L; u1 [5 |, ?& q                        fresult += b1[jj] * b2[jj];  ^5 I3 x$ B' s1 ]! X' y, o! @
                }
9 D* }& h$ i. u8 q1 Y                */  R9 j- n7 B( Y2 Q* K! O$ Q

* q% I2 l, H1 s( w( x                //Method - 4   202s
0 @* t3 \! M8 j8 P  D                /*% ]* s% @' Z5 x2 g+ I
                for (int jj = 0; jj < N; jj++)9 d+ n! i1 |7 W2 i2 c
                {: D5 T) P8 P# l+ {. B& d
                        2 t" A0 K. j& D+ @2 M. C
                }
/ W  |! b0 _0 Y2 F                */7 \  t8 U0 ]$ Y; V. s! R
                //comment out all methods, N=100000  202s               
* b% R* u$ g1 S% s9 j/ t        }4 k# t: g. P$ M" h( G$ n

5 e$ E' K  w! F$ |* J        delete []b1;
: J3 `1 L! W# {- r# L  e: h) {        delete []b2;
3 g9 j6 O- x( l. J

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
, `, u  A) X* ]3 G- M) i" v" j: C# Z% ^" Y
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?: R4 h& z! k( \

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
6 Y9 j8 N. N& ?! e; r瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
+ h9 p( y/ `0 g3 _# y$ L
$ S4 \1 R* e6 e, A7 g8 p# _) V你第二个试验里面的j在循环里面又重新定义 ...
- K% v5 [& v/ [3 E
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL( n- {* q6 g( o+ z

# J8 {! N' j5 T) [) R不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:168 H2 `9 F" x1 d5 d, |
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL( j% |4 ~; y6 s7 k
' y+ C  J4 |9 e( @
不和它 ...

3 S, z, |" h2 b( U5 n" B3 _3 u. G4 ]8 h0 x- W3 a5 Q
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
- d& H; _" a! e; v7 J) ^! s后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54  q) S' G! h! j
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' y" V! g2 E- F9 O: c{& E1 s) i% D8 N2 ]2 A% v+ ~
        comp temp, xtimesy;
! N7 J1 r+ I& q+ {6 f! q2 N, f4 g
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。' D6 O! Q/ ?0 n% d8 U: b- y6 ]5 V- K
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?6 {8 X* g% j$ d, M. i
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
3 w5 D! Z  i& K: p% L6 l理了理思路,重新做了一个测试。
7 y( I8 S3 |6 a9 P6 ]9 L/ c7 d, a做了两个 vector 和 两个 float *, 都长 1000005 \+ M- M7 [2 y7 q7 }1 K" d. F& M& S
外循环 6000,里面先做随 ...
! j2 a3 {! ~; K( T& D5 v
这个时间是从哪里开始算的?( I5 T% }$ P% y, O1 Y8 ?
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
$ A% ~5 c: M. t3 N0 W按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39& u. J6 l* i  }0 g. H" _/ C
这个时间是从哪里开始算的?
* j3 \3 R9 D% \我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

/ {5 o1 M- p2 h7 a我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。0 y4 S% u; f' E0 m
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。4 _6 L$ f/ `5 f1 R( k
与此对应用数组(指针)花了2S- l% c8 ~- F* m. n
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54+ n7 O" P0 a3 g$ D
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 j8 Q8 \1 S* m+ P  {, |
{. i# Z% Q# f  @0 k* I7 [
        comp temp, xtimesy;

) f( O7 }4 D. f) j1 y0 u# |: s我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
! X- {  z5 e- v8 t( D5 N% X0 K; n
4 \# }4 t* V8 T! i' U
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:290 B* K7 |3 d  h2 o7 o- `; M& v
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗, N7 m7 ~8 H& \7 D/ b

% z; i# B6 |# b ...
( e, M1 V8 P: u+ A9 X5 X' g  R+ P
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
! \/ J$ u# X- w$ |9 w* {1 F# U
% P+ o, w. K' b2 y7 |2 n$ z雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
* A% E" J8 r+ b
* [" B2 X! [$ z* ]( i2 u, F是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
3 k6 l0 W$ _' `. X有空时我会试试 SIMD和并行,看看能提高多少。8 e4 D3 e; R% k& O- c
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。
: t% C6 U) ^" p7 k2 |谢谢大家的讨论,I learded a lot.  红包已发  
' ?! Y4 C$ ?* c6 U& L
8 \% j, D# g3 d2 G
3 |( o1 U  g% I" c/ C# T. X) G
, S/ j# m# s5 y3 r3 K4 q3 k. P' A; M" f+ S; L/ q' j9 L6 i( {* c' k





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