爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?! o5 t) @9 w7 i' c4 ?
/ ?, k. x6 A  M% f( v
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。; ]) f3 u. h# `

! @4 B7 k; G" x, o- t8 D速度优化问题真的很有意思啊。
6 q* H. V5 M7 x' _
& A' e0 C4 t, F8 E, y0 j& _# U) N欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
) ~# V7 T4 W8 N把代码贴上来看看?
5 t5 c+ r" _- Q4 v/ ~  u" L5 `& {) {: p0 ], f/ J) j
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 7 k+ D0 \5 a1 T4 A
数值分析 发表于 2022-9-24 23:04" e" v  S( D$ m- X
拉下来?拉多少?
+ ]! h3 p6 Q8 ]% A/ e8 E把代码贴上来看看?

- l8 N! P: p" y% i, x1 x' Y3 {6 p' V6 c" ]+ {/ Q& S& h: c" X  `
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
7 K6 A* q( X- R7 i2 E8 E{
" o' N7 Y6 \; T  a        comp temp, xtimesy;0 s8 m! R/ O' w5 y; F
        xtimesy.re = 0;
2 [' q4 {5 T. I9 F3 m. R        xtimesy.im = 0;2 f4 i$ n8 \9 p$ U5 N2 g- i
        int j0 = lenB - 1;
: v- v( P  S% z& c1 g        int    i, j, i1, reali;2 d- f; l4 G( P- ?
        if (lenA % 2 == 1); U8 p9 ^( H9 s+ n+ m# ?+ I/ x
                reali = lenA + 1;" Z! V3 t) M6 A/ m) i) N1 f
        else1 M# ?; }' j, E/ ^+ L
                reali = lenA;
" B' Z6 I7 p( N' c        reali /= 2;0 d$ r8 G& o$ f! p7 V1 b

: X* ^& V4 l! R& u, U& K        int nconv = reali + lenB;
( t- A: {# J. j" P* Q        //#pragma omp parallel for
4 s+ o, E4 A2 }, q9 w5 W2 }        for (i = reali; i < nconv; i++)* u! M: F0 R! \3 {! t/ j6 Q
        {. W- T- u8 D. U' r8 w; t  R
                temp.re = 0;: e" ]- j- |1 t5 S9 r
                temp.im = 0;
: r( m3 |* d( Z( b, W% ~                i1 = i;6 f( J7 k9 S4 h& a% w6 h6 |0 _
                for (j = j0; j >= 0; j--)* [2 P* F# ~: Q/ \- @1 |' h
                {
1 Z$ I* w) ~$ s                        /* floating date operation */7 e, b8 r- w- i
                }
0 y: P) s2 P0 J( l
        }
6 _  b# O0 z/ P$ V5 S4 z}3 G$ g% B+ x3 W" b# N
" z/ n/ m7 C. R1 @$ s% K3 r
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样8 k  i; j. }, F" u

+ N! ^4 P( \+ V$ }红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
2 U% w  U5 \) ]( V2 H现在call xcorr 100次,耗时78s.8 `, X5 F) K& |/ I! @! D& e

4 x( k7 U, S$ E: y/ W$ Q如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
  U8 ~9 Z" E9 T3 x( y  k6 |  M6 b. F! |9 t, Y1 e/ G) B3 t0 s$ c8 ~- {

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33% o: Q0 k% u. H3 |& a2 o
Maybe Debug mode?
/ X& C% ~6 |+ c4 U
  d  j, ^# ]- B) \1 `
不应该,看我上面的回复。4 a% Z" Y' {: A5 s& M

. B+ K' o" u: I& X7 `我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
0 Y) }$ h9 w3 L0 L
雷达 发表于 2022-9-24 23:543 x* }8 U2 [# ^6 a  Y# u/ R
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)2 p- q# D& ?3 P5 l
{
5 C# z) Q( `( n+ f  o        comp temp, xtimesy;
/ R) R' h) B4 x( R; u9 Y/ N

5 O: [3 B6 [, c$ B9 p( F- b这个不是这么比的吧。。。! e6 Y) t2 s( I- |, O

% V, l! @. `3 _0 G( Z& d& |- o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
; a" k6 y2 Y6 ^+ v0 N7 V0 h9 o% t
+ @. |' `: j+ h! J& u( @而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 , S/ u2 c' @$ A' V8 J
数值分析 发表于 2022-9-25 00:20
  ~  J! v. J6 `3 M8 y( q2 @这个不是这么比的吧。。。
& x3 ^3 E2 C5 t3 l2 ^+ _- r9 Y. [' X) r8 c' Z. q
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
0 G+ z; k6 d) k
6 Q! k" i' E8 _) P6 b" Z- {6 r
有道理。- N1 y& m. {0 T9 U, \6 {( _
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。- u. w, a$ ~8 P  }$ z
$ N7 f9 D+ X  ?! S0 h
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
3 u# u: L* i9 g( @$ d6 t7 Q有道理。
) h% [+ n# q' t4 I% i, e. M5 U所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

4 ]" l) B6 c+ v: D, I) C( j; H你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多1 K; C' c; ~& W9 m& S4 M
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
& V% Q- C" b! l9 X3 x1 z这个不是这么比的吧。。。
7 A9 T7 T) [) r5 e; e+ S4 _7 X2 |, ^$ E
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
2 G/ H, ?4 c& f; O" Y! {: _2 W" O
% r0 B9 N' Q, `: U
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
! Y, ~, c4 |  M) l; U2 R( Q
沉宝 发表于 2022-9-25 01:48% y* W# t+ }2 ^, {7 u: R2 |, ?
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

, f( i/ {6 F" C. [/ I- J4 ^+ K3 d' L& d* I9 e" {5 h/ ~% ?
是的,兄台说的对。- }, z# j+ l1 C

# o4 \& }4 D2 @( `) l3 L& E其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
8 T9 b1 O+ ~# Q# j. L# c
! W* m, g' h$ @2 z8 c' [雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。6 \# i6 z" t; ?$ T+ N5 T# p

1 k, T( T; k( K: V9 A7 d$ S比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
2 L& L/ A+ f: d) m: o/ w/ d' \& C9 g: N7 Y
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
/ a( H3 x4 x) K
沉宝 发表于 2022-9-25 01:27( k3 y" ^* V8 o  u
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

$ ^/ @  I  i; A. B) Z) ~( r( b8 u+ j1 r% E
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。0 o, X% G2 d0 h( c1 g

% z2 H: N! X$ y3 A/ j# s! n我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:471 {( I5 V3 y( X; q! M
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
8 r2 a! C3 x2 I
时间差一倍的结果可以接受。1 m5 {1 W% ]/ U* l! G) w. M) J
. R6 @8 D: d6 Z5 W% c* ?
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ! S+ a  A1 X7 ]! U
雷达 发表于 2022-9-25 04:47
: S7 D$ U! ?1 f" o# m又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
" r  Y; ?: I5 j7 J

* u8 u2 b1 M3 r' E+ `* A
1 r9 i: Y" y# K1 w0 j, [3 z& H. l9 A7 b% \! @- U
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
% @3 H) k5 ]8 ]/ d4 K# w
数值分析 发表于 2022-9-25 14:58  w# J, V! d6 \, @0 i" |
能不能把这个也贴上来,看看和上一个有什么不同?

8 U# }7 C7 }1 _! m- [理了理思路,重新做了一个测试。
: Y3 }% }6 [( A2 y) A做了两个 vector 和 两个 float *, 都长 100000
5 u( J% a- G( d+ M外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.+ n7 r& v: K- A7 Z4 m1 N! C5 T8 }; i
9 M0 r$ n1 }; c' D
内循环试了4种方法,
2 X/ |) h- I: ^2 G: i1. 直接调用 vector inner_product 247s
1 M' w  R( V0 Q  L2. vector 循环点乘累加 237s
2 S' J& g" L4 g* l3. float * 循环点乘累加 204s* V5 r1 l! Q2 [# U0 G
4. 空循环 100000 次 202s
7 g* ?, U4 t  V9 p5 X& ?6 P
1 Y$ s# s; i. A& i# N0 x不做内循环 200s$ i5 D9 w0 i2 z4 X6 R1 W. _, }3 s
$ S- O/ k& n& w8 S, t, e+ Z
你昨天说的对,内循环本身占比是很小的,大头在其他处理。6 `% d2 G6 v4 v
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
' A! m/ t% U' Q& d, a6 h; J& F$ Q, v/ w
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
, p# Z+ C' p4 Y2 ?2 ~; C" i1 ~, Z, X" w
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
4 [: z4 i3 G0 w/ ?* q
: X8 _$ t4 Y  m+ I) {
        std::vector < float > vec1(N);# r: h: f- n- M3 _+ H
        std::vector < float > vec2(N);
2 j, I/ z1 U% X' K5 x. |        float* b1 = new float[N];
& B5 B1 l! C# @/ u  G6 y. X% p        float* b2 = new float[N];( C9 u# t1 O# p' S4 ^/ m3 b
5 X! r5 b/ v; _9 d
        for (int j = 0; j < 6000; j++)
* w5 f3 a) \! B        {
) e" r2 ~: R' H/ K6 ^3 G                std::generate(vec1.begin(), vec1.end(), []() {
% X: A# z; W% @: Z5 \& `                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;0 l* P4 U6 n. N1 I$ f( z
                        });  @; l: w' T; ]. j1 a1 \
" x+ |( P1 }5 d
                std::generate(vec2.begin(), vec2.end(), []() {( ~1 ?5 g% i1 X" ~
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;" w# J1 e! R' x0 I7 g& `
                        });1 t; Y' Y, I0 d
* i# x4 m: o8 X" h3 W2 L' F& r
                for (size_t jj = 0; jj < vec1.size(); jj++). R( T2 |" G1 h0 H3 O% v6 M
                {) ~7 S1 S+ C8 r7 o* v$ @
                        b1[jj] = vec1[jj];
. o  t0 S$ G7 M. J% s! t                }
" h0 ~- p$ M+ A6 k* M- p2 S& ]" j, p1 X
                for (size_t jj = 0; jj < vec2.size(); jj++)
! p% ~1 p* o' N: g' W3 y                {
$ C! k9 r' K& f7 ^$ O/ v                        b2[jj] = vec2[jj];
8 N" x" _) W, t* O& g                }
, N% H1 B% H+ J# \# Z
# i, f8 H3 z. ^                //Method - 1  N=100000 247s  
1 H$ W1 R$ L1 p: \                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
' V0 Q* }; u2 T, @. |; ]                                
$ Y- Y3 W* r- @, \' [: ~. `$ r/ d                //Method - 2  N=100000  237s
/ c1 ^, Q7 f; K+ v2 y                /*8 V- j( c6 I5 `( }0 I3 D' X' p8 @
                for (int jj = 0; jj < N ; jj++)
4 c) ?( V6 P! l3 I                {
$ d- J+ F. o  ~% r: j+ T' z" b! H                        fresult += vec1[jj] * vec2[jj];
# R) ?( Z* s6 ^                }
8 n6 B7 [# [' |/ `" z  }                */9 p: o9 h9 R5 S9 t
                                , a$ {9 W; h  }
                //Method - 3  N=100000 204s
2 C9 j. ?. k. k$ C8 q$ Y                /*
7 p& D  H8 ~. Y& `9 k                for (int jj = 0; jj < N; jj++)8 E$ l( n9 l2 F+ T
                {; Z6 R: |* O& N1 i. {% S9 I
                        fresult += b1[jj] * b2[jj];* O0 L& T- |3 ]5 I. ?  Z8 g" Y
                }
  S( b: D  p8 W* {. r3 A) s                */
7 a" j( ?4 o( h8 o6 ^2 X; A+ p. S" u6 h
                //Method - 4   202s6 [" }: M  m7 A2 U8 h- C2 R6 u
                /*& R$ j' G2 ~/ d6 S! H: u1 l. B1 g/ ?
                for (int jj = 0; jj < N; jj++)
  G  W$ M3 B! ]3 M; q. P* P                {6 Y" F" {4 }6 l
                        
5 D- }! {) h* |8 r6 H                }
# i" @( f* `. g. R, r) z                */$ o4 J! ^1 P$ x7 v
                //comment out all methods, N=100000  202s                ' B1 R9 Q. u; Q7 ?
        }
  v5 \- z" x2 O! S
$ m) [9 E5 Q; f$ ?) R        delete []b1;$ u5 j' l& b' K, U9 n' k* J* `
        delete []b2;
# m5 |; |* m' R+ X! [; g2 B1 \

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
8 E3 A3 o  X& O: A) Y  _: j
! a$ q) A- o1 \% \' j6 X$ ]6 F你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?" N: F) |. I+ r2 O" h

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:156 f; q, {, ^" f5 q. ?" |# B
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
7 @, A, P/ T1 x0 F; ?6 `& `0 ]: ~% A, u+ M
你第二个试验里面的j在循环里面又重新定义 ...
, b  {) r8 M. L" E) I  S( X- D
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL# K0 Q3 U% F/ X! t$ A& a
, {2 {& }9 |- a2 I) o* [4 w; d
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
5 w9 U& n5 W% `内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL' C: E# \3 f6 G: `: k

$ V: `" [) _6 l8 B不和它 ...

; S7 B- m$ f9 ?7 U- E. w" l6 f" _
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。9 }( {; e' S  |* V0 m# f
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54, G4 g7 L" }; a" p* w" ^
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" _; g. b# A( D7 r, e
{
- p$ r* r. g8 T1 @* R; I3 {        comp temp, xtimesy;
% R5 X2 k% p  n' ?
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
3 V0 K' _/ S+ B" L% f内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?' D  k. f: _$ `- P+ Y  D. Z
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
/ {* |2 L  v, E8 L& ^' n; `理了理思路,重新做了一个测试。2 x0 z1 L8 L8 ^- e6 a3 _
做了两个 vector 和 两个 float *, 都长 100000
3 |& ?4 b7 x- Y  `6 ]) z外循环 6000,里面先做随 ...

) w/ D( n6 H) L! n8 G/ M% E- N2 G这个时间是从哪里开始算的?. @( {# I( c* }7 w# |
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
9 w2 [: ?+ w1 W& n4 N$ q4 i3 N按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39+ O7 H" T8 L* f' H1 k9 Z5 _8 Y
这个时间是从哪里开始算的?. i% y- W7 Z4 ?$ B4 `1 X
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

1 p; B. _4 a1 p. k/ z% ~$ X我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
3 |8 X& I4 G( w+ O# A你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。. W( n/ I. o& s9 b
与此对应用数组(指针)花了2S" |0 l  y4 C! x6 S9 t* R
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
! Y, ?( E! f3 b' Z; z1 F% T* Q2 U1 Uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 a/ H# o( _% T, \& X$ O/ i* {6 b
{' ?6 n' s, _6 \( Y% N4 r5 L- u; y4 {) {. `
        comp temp, xtimesy;
; k9 }+ a6 }- o8 T" }$ U/ G
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
" c5 u% K/ i3 L4 H& R( l
' S3 m, z7 J7 t4 D
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:299 L  z5 w& v" v2 p$ f
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗- I$ c% H6 R) C0 ~7 l: s2 m# K
& j/ @6 _7 I7 W4 W. ~) u  N9 z
...
5 F/ E5 e1 f0 ?+ s- R0 h! m4 F
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。. c0 X2 o  p, O3 e& U( i4 r

5 q' |+ B2 g( j: ^* M雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
2 ?( k3 m6 S/ ]8 H
& c) V. K9 I/ p; E3 h是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
; H( L, }( c6 o9 E, f! k有空时我会试试 SIMD和并行,看看能提高多少。. O8 j: J" H$ a  d: S* N* B
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。6 g- k0 R$ n4 c- ]  u7 `
谢谢大家的讨论,I learded a lot.  红包已发  
2 [9 Y3 G$ e( b* g8 a7 M( c
& q0 ~: \$ T, p5 f4 {4 S
5 V7 V7 L0 O2 N, W7 [  [
& W( q% c" e2 ?& _3 n
% i  R5 m7 H5 T* |! G" r




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