爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?. g& F/ K' O* h! v' r
7 E! M3 V: Y  y+ V3 p, O1 {/ _
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。6 ?, D# `/ U5 T% o$ l3 P5 }
# T* q  X/ g$ x/ k: M9 m6 A
速度优化问题真的很有意思啊。' _2 @/ [  i4 c2 e# b! h- S4 W

8 r0 L  _7 h) E& @: X- k欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
0 Z. p, T, ~7 ^把代码贴上来看看?, s% j) p) \. X+ E7 M0 ~, s

$ p% T( u6 b  }# u1 W/ a1 l. l. e0 @难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 : y2 C9 X  v& C
数值分析 发表于 2022-9-24 23:04
$ m* M  n# z! y2 s% ?! L+ M9 p拉下来?拉多少?
, v+ F) P2 b& G  i1 K( B2 n; z7 w把代码贴上来看看?

' W8 R' N* X. c, a: t* S% c' Z, E+ [
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)3 D- g2 b. F4 X, J9 L  x
{7 P0 t5 J* E8 A2 Y4 ^# |( @" Q
        comp temp, xtimesy;  z9 g5 C' `/ P" _7 I0 M
        xtimesy.re = 0;
  U" a% ^1 k+ Q7 N" z        xtimesy.im = 0;
, s! u* s1 _; u8 q  c' G3 w        int j0 = lenB - 1;
  |! i/ q$ T" G6 R! d" t        int    i, j, i1, reali;9 J5 ?0 [( H' a- ~
        if (lenA % 2 == 1)# d8 e  z! ]7 \" z' w9 {9 V4 A
                reali = lenA + 1;! g9 c: }! s" I5 q" g  n2 P; _
        else
3 `9 ]7 ]& ^% [2 O* W# G+ s3 o  B                reali = lenA;( @, ]4 E0 Z; E' ]# o
        reali /= 2;
8 K6 b; Q. h7 j# E
2 i0 r9 j+ U8 \3 G% W4 e        int nconv = reali + lenB;
( f$ p( I. o0 V. K) w: s        //#pragma omp parallel for. n# \1 a7 R6 ^/ b
        for (i = reali; i < nconv; i++)
$ {9 t4 ^8 R2 L$ K* T        {6 E& ?6 n9 q5 H9 o+ P) u/ {# l
                temp.re = 0;; n/ ~  x$ H# s* F! S9 z2 C! Z
                temp.im = 0;
+ K+ n$ G$ Q2 _. N5 u/ i                i1 = i;  V/ ?% W0 `  e7 X6 w
                for (j = j0; j >= 0; j--)9 t* G' K0 o' ]) ~) w
                {9 I0 D: |3 O5 |# U0 L* E
                        /* floating date operation */# V7 {. O% g3 y
                }
9 @; {1 ]- O. `" Y
        }1 x4 r; [: Z/ g4 x  r
}
8 z' n( ]& j- t. y
! B  C8 |+ m/ ]3 a. Q+ C( ]xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样# q9 g' H9 D0 E5 J: [

3 {7 B( w" D7 ^: s红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。0 O8 t/ I/ R$ w# }# h( y
现在call xcorr 100次,耗时78s.& x- f7 H$ }9 p1 t6 f* w  e
6 ]" W$ A7 h6 P. L& W5 b
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
/ g. z% {+ W6 t) t) o/ R  O
- w( Y2 L9 S/ P* a) p2 @
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:337 r( b% l! N! V
Maybe Debug mode?
9 p) K' y/ a. H- Q. E+ f8 i  N

0 C8 Y5 [0 P  W$ q- s8 W! s不应该,看我上面的回复。' d, O7 a  }! V0 }, Q6 K* w

8 z0 Q+ A( T. w6 D, t% z# l) i我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
. u7 C6 l9 X7 }' m5 r) _% ?# T
雷达 发表于 2022-9-24 23:54
" a/ Q: G6 X! x  i  Xvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( ^7 Y, p! m( {
{
$ Q+ Z4 d! T- w- w1 v# Z( K        comp temp, xtimesy;
4 `- y' y# N' N; Z

$ M* F  D7 P* h1 ?& M这个不是这么比的吧。。。  E! S  _  i4 E1 Y+ c
9 A- Z" n! L) i/ D! f8 Q! R8 E. C
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。( ]3 s! r9 O7 j5 M

0 b0 q! ?( F5 n( A而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 8 q/ J; z. {# X7 k' ~
数值分析 发表于 2022-9-25 00:20% P5 u! n; f" i# T( }) Z
这个不是这么比的吧。。。" L- q+ h" H  R, I1 |1 f! ]" P

; H0 D, N& ?7 |( W& [3 k( ?+ q您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
! `# S" p) U$ B2 a+ ^% f

! q3 F+ J) U4 W/ n4 W有道理。
. q9 B9 e8 ], T# D5 R- X# v( ], h所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
6 r: W2 ^& o3 c$ G' f5 U: M% h7 o& ?7 L$ ^: C% i. A
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46; k3 T& p& ]7 r' T, l
有道理。! c) @' u  H7 R$ z% J
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
. W8 R' e0 B' e. ~3 r+ b( s
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多/ L% B' z: ]. @$ `* h' T
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:209 B8 i2 w! B2 P& w8 p+ v
这个不是这么比的吧。。。
" X- `- S( \& _
: ?/ h; n+ o& \3 S您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
$ n9 V% H$ c; C5 O5 ?$ f" h* M) o
' P; Z5 U7 U8 p" l# B
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 2 q; U% w; C; q+ ^/ t
沉宝 发表于 2022-9-25 01:48  m0 c$ X. l& M
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
, G$ \* H  r+ C: e8 u
. |# R% g# G4 y$ K4 M
是的,兄台说的对。3 t+ X2 _, d( `6 ~4 ^# ~$ R' m- U

! N5 f4 @7 n% C- k7 j2 B' a' D其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
* u) B0 M3 S" m( |
$ L; z5 a& J/ @& f雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
; f) n. O- G# x7 e5 j
( e6 ]" q9 }) X9 f6 w) Z比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。6 B- |: _( b9 X

+ i( W+ c1 n& V当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 $ X% q) S9 n6 j4 T
沉宝 发表于 2022-9-25 01:276 ~, U$ j5 w' N; D, h
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
, b* h1 E, l8 U7 X
2 L$ A# I5 `  g+ Y' S0 J, O
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。/ R2 C, _$ r$ c! U- h4 K2 o

; P' r0 W( Q) T我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47* d- T5 G! I4 F
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
" Z4 E% P, i8 o9 S4 K, W" G
时间差一倍的结果可以接受。8 _7 \6 i) a. j5 \% D' r9 K

7 m% r+ e/ [/ j" j你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
1 k0 \0 z# X! F5 {. {
雷达 发表于 2022-9-25 04:47
- j0 w- N# d5 K" O又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

( `# T  y# B7 O7 `/ K9 G# K& ~2 H& b, p" Z1 T( `' R/ R
$ B& w* c# M6 O7 f; f% ^& a3 i" ~

8 i% M% h! T' z! J& [9 m能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ; M2 y) H3 I: J7 m
数值分析 发表于 2022-9-25 14:588 I# Z" |! X, I* ^" T. G
能不能把这个也贴上来,看看和上一个有什么不同?

6 ]# W$ D# R3 [, F2 _! l+ @理了理思路,重新做了一个测试。
4 ?0 t9 [4 h0 N0 [/ D5 q3 A1 n做了两个 vector 和 两个 float *, 都长 100000. x1 g7 K( A, T  v
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
/ N8 s; z! q+ S* w6 e9 N& j& c- K" a. X# M- i
内循环试了4种方法,
; N. k0 G+ Z1 l5 B7 H( s1. 直接调用 vector inner_product 247s
3 Z( h4 H) }  s6 O( W2. vector 循环点乘累加 237s; n* d) x$ g$ J  f, h' {
3. float * 循环点乘累加 204s  I4 t! H3 o, e" x" p% w* X2 [  N
4. 空循环 100000 次 202s
+ Y- d2 _: a6 Y4 \) E+ V2 ]
1 ]8 T2 A% d0 L% i* ^6 P不做内循环 200s
3 l  u5 m* L8 c% B
, Z( u8 F# B- R# U7 S你昨天说的对,内循环本身占比是很小的,大头在其他处理。
* `. @' m" P. K/ z+ n2 v* X另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。- Q$ Q7 N8 a- U6 v, `4 ~. l4 A

: v# z% Z5 {: b" [' C( h+ a6 T& E至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试); G2 Q* H- `( R

  l. q( B& x/ c8 ]$ F: r(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
3 E- q$ }6 p* f7 M$ C( ^" A( z& s- y- R+ m  D6 G8 J
        std::vector < float > vec1(N);
6 h. [0 Q( ^9 B, H* o9 _8 v        std::vector < float > vec2(N);2 a$ y2 M' W" p+ y% [( N
        float* b1 = new float[N];
, k5 C, O2 ~9 ?# W" O6 O5 y        float* b2 = new float[N];
0 v0 a3 @6 `/ c: `" `, @2 v
  w8 A) J2 Z& N$ }' H5 C( Y6 ^        for (int j = 0; j < 6000; j++)2 J$ {! [- Z4 w; A9 O6 p
        {4 F4 [' q) @0 y: D
                std::generate(vec1.begin(), vec1.end(), []() {9 l: w; ]7 k5 c4 _1 n- }6 D3 _
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;7 g& ^* t+ B5 I6 n6 c  g
                        });
, ?7 F9 E6 o  N3 R$ ]: f2 ~& e7 V) _& b5 V9 u. {% b
                std::generate(vec2.begin(), vec2.end(), []() {
- K, R$ i5 \" ~1 N7 m7 j3 Z                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
) ^' |1 w8 `0 r8 R. e$ B  Z                        });, j2 W; r& `8 z: ?$ M! a! U' J9 ^( F6 Z. @
: d: W  t' l; c4 y7 t9 }
                for (size_t jj = 0; jj < vec1.size(); jj++)$ t  l: U; O0 \# l: W9 K  V
                {
: t' k% s* ^" ]$ i% e0 {                        b1[jj] = vec1[jj];
, ~- [- W% ?, |+ f                }
  Q+ W& Q- b& N5 v! Y# ], E5 s$ Z+ o" d# A* M
                for (size_t jj = 0; jj < vec2.size(); jj++)
' f, W# g5 V& g9 ^- [) E                {, n) c  \8 c& [: C* ]- Z
                        b2[jj] = vec2[jj];
2 g% ?! V; o9 @6 e5 i                }
7 e# W) E+ g9 I% A! u/ @% _0 z' K. F2 J0 ?- W5 i
                //Method - 1  N=100000 247s  
. R) [) j. Y* \- \6 \" R                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);( S% i- o1 C6 d0 T/ I8 X( M
                                : t: ]+ Y" X/ r! i" A9 M. R4 p
                //Method - 2  N=100000  237s) G9 I1 Q5 S, s, h! X1 B
                /*+ c! q# @& `# p% F
                for (int jj = 0; jj < N ; jj++)1 `' j/ O2 S( H7 o8 J- }' X
                {
* N, I: g, @! m. {" F. b; t6 B                        fresult += vec1[jj] * vec2[jj];
1 ]' E6 f8 s2 b; b                }$ |8 y" o, S5 B* R
                */' m- O+ v& Y5 C( x" D  I
                                
! q  o. Y' S+ b; ]  u                //Method - 3  N=100000 204s0 j2 m; E* T8 f( o9 ~9 t
                /*: P1 S1 D! {. F7 D$ A
                for (int jj = 0; jj < N; jj++)
, Q+ b/ o7 L+ c+ o" z                {: E+ U, n8 z% Q. b( y
                        fresult += b1[jj] * b2[jj];
5 q: p4 B9 Y5 {) u1 q* F4 c                }
' d4 M4 y. ^; l3 f- X7 Q                */! M/ Q- m; m2 M% t
8 F1 K9 C2 U, N- g1 _6 h) s
                //Method - 4   202s
# g, h# s  \& v9 P! y3 C                /*/ w0 i# k' E, p1 C% E; L
                for (int jj = 0; jj < N; jj++)
6 I; ^2 M+ K1 Q# X                {
; t. U9 L, G0 T+ T: F- ^; u                        
! L/ c; T9 m% D  v' B1 ^; c: q1 I                }7 a: z" |" Y6 o/ y+ Y
                */% |. q! O5 P& H  ~& i
                //comment out all methods, N=100000  202s               
' H0 v+ S  {) O- b3 |  D        }8 u. o, Q& N' M" E8 L% {, H) e
# Q: B- X6 D* [0 `
        delete []b1;1 b* q2 E5 s5 |
        delete []b2;

$ ?% E+ W# ^0 ~3 |( Q8 M
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?) R. N! s" ?" V$ p* K# A5 e$ a% K) q

8 c8 L$ u- U1 `* s. R  P3 z+ e你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
( P9 O& [+ o! @: S1 I- {& s" H. n; q  ~
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15) c. L' \% g; S6 ~( U7 c
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?. X5 J/ k/ Q# E$ R7 }% F$ C

4 z) ]" o' k) @" c4 Z+ A你第二个试验里面的j在循环里面又重新定义 ...

' j8 u3 S' S$ B; Y$ ^5 f内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL  T5 n/ a9 k0 m0 m" ^$ c9 K

* z; R9 Y+ \4 h0 G, i6 |不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16) l+ I7 E* U8 m1 v$ O
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL6 T% s+ X: K* \  ?
* c) G7 t% q( Y7 p; b
不和它 ...

6 j6 z# g' u8 d- U5 `% a& o0 }6 o9 u, A
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。8 V6 Y0 w1 V9 ?$ W% x: i
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
0 p; [/ E+ Y- s1 kvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
2 I4 z2 H& s5 d) i8 g; X{
4 N* @' {6 _+ g8 v1 F1 ]% N        comp temp, xtimesy;

/ d" q# }8 w+ s7 }5 |7 O1 X这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。8 c" w+ r4 A! f* ?' \
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?6 \& u  |/ @5 U5 P. T' B
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30# L+ ^, c2 t# F1 z
理了理思路,重新做了一个测试。
- G/ w" E  |$ l+ Q! ?6 @做了两个 vector 和 两个 float *, 都长 100000- K; h! M8 L) ?; e- H. e5 \
外循环 6000,里面先做随 ...

( _8 \  Q# t% t: ~5 \这个时间是从哪里开始算的?! T' V. ~. ?2 f$ I
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。6 @0 v  ?4 P7 s  Y8 u
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
) A6 R* u& }# ~; E这个时间是从哪里开始算的?! q, F- ?# |* N3 K: T) |: w
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
- G$ j0 `* E* B
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
; ?* |, V; g- I6 J/ [你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。* M6 \  }* l% {2 o* v
与此对应用数组(指针)花了2S2 P3 K1 t9 C- s( J7 Y, H( z8 i
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54, t8 c% x# S5 _% N+ z# r, K
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)1 A& Y# g6 z! Y1 R/ W0 m8 }4 o
{
' j" q) E% s0 e* `6 i        comp temp, xtimesy;
8 J6 M! t- g: z/ \! N; a
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗- @8 x* _9 |) T0 `  h

2 C$ Y- p) M* `4 Y
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
: }: u8 J; c, x  n4 P我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
6 P* w& I, i) C* \1 o$ ]/ o- w0 `3 \% k) K* e
...

. m' j8 n' P" {你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
: B& W/ S6 O+ C. e# Z' `. |, B) p5 A5 r0 c! ?
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ) R; l/ I8 e! v5 S9 {! _
7 b% v/ g3 m  N) ?9 e
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。  A3 e7 @& @/ V$ S
有空时我会试试 SIMD和并行,看看能提高多少。- w0 i0 O4 {  X$ h# q3 l& |4 M
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
/ V( G; W- Y5 V" {) f3 @谢谢大家的讨论,I learded a lot.  红包已发  9 W9 a8 R+ s/ |, [  e

- c! K8 L& L. K/ K5 `2 a( t0 t
8 i/ J$ ^/ y, ]" f
2 v& F% R3 W' y! C% b! u
) F6 a6 j1 ^* J* j- `! H* Y6 d




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