爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?# P$ l7 x) I1 S) e
  D5 {  `. R5 @0 L! p
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。+ d1 a9 z2 s% X

2 t3 w7 I0 ^, _' K速度优化问题真的很有意思啊。
0 \; E4 T& g9 a; w: R; G$ L
" w9 E# `" C& Y- v7 P欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?& @. U2 G/ R* p7 {; v( h
把代码贴上来看看?+ D- N0 @* Y' n1 c

1 ~* }8 w" i+ K. Y3 a/ M; T难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
9 u. n5 h( T1 [" F
数值分析 发表于 2022-9-24 23:04/ Q  g$ V5 n, R4 N
拉下来?拉多少?9 H' u' k  R) e$ Y
把代码贴上来看看?

1 ?: I* J  H, o8 M( e: J' b* e6 J* h+ L! [+ g  h8 V1 I
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)# m( F# H3 {9 }2 F% T! v
{
+ Z+ p6 t. f4 q: g' ?        comp temp, xtimesy;
' F$ q( R8 {  h) f        xtimesy.re = 0;; n8 B: \9 B& b0 y/ j& D
        xtimesy.im = 0;; j2 M3 P7 @: a4 h9 ^2 p3 K4 F
        int j0 = lenB - 1;0 U# [/ D' n9 T) \8 d- o
        int    i, j, i1, reali;4 T2 D  _9 z4 _- V
        if (lenA % 2 == 1)! u/ `6 x. Q  p8 t' A2 Z4 L; t
                reali = lenA + 1;: X( [0 S) Y, s/ Z- Z
        else
% B; U5 n- q$ s: z                reali = lenA;" X% a8 ?* V! t0 T' ^; l
        reali /= 2;) d+ D5 H" P$ a. [% T+ c

7 T) S8 k7 c' [# {+ {$ \' }; P: u+ A- q        int nconv = reali + lenB;
. j; U9 C" [# U6 P' p! L! `        //#pragma omp parallel for, f1 e3 n6 d) o  o5 E/ M9 U5 f7 u
        for (i = reali; i < nconv; i++)
$ W& m$ E7 d' ?1 j        {) _$ ^  V3 K2 Y1 n
                temp.re = 0;
( s' h! v. O4 m# H7 q                temp.im = 0;
7 Q* l$ s6 R+ ~# L% H                i1 = i;4 u$ {1 p$ S7 u1 l+ R
                for (j = j0; j >= 0; j--)  w( X! w( u, e2 Y/ h, u
                {  P" D8 ~) `$ T4 |$ ~& L- N: b( C
                        /* floating date operation */# [+ V' K9 d- d. ^) O
                }
$ z5 e/ D/ ~& j3 L3 z/ m
        }/ S# b9 |8 M" H
}
# h. J7 t* V$ d3 F
/ I  z( \8 F6 cxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
4 _$ A  {6 y6 b  `( B' b# C6 n9 s* Y7 h7 J$ E, f! D% x# w9 u
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
+ `8 A4 E& _+ m& @( i$ M6 X$ S& R现在call xcorr 100次,耗时78s.. H2 o" J6 k4 w1 u& _9 v6 H
% i1 U$ ~0 ~9 ~
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
" P9 H$ T. E- n" |5 S3 p$ i- n1 k' C/ F: @5 I: Q" z

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
! U9 B4 b% L* _7 G4 ~Maybe Debug mode?
5 s6 M. l' c* i& N! `4 ~; J) @

$ v" J  K$ o5 P不应该,看我上面的回复。
4 O$ u% J; @7 Q7 H1 w/ i3 y
% h; A8 s5 |2 ?5 X# S5 [我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
* [4 K# e3 o& M5 ?/ ?+ w
雷达 发表于 2022-9-24 23:54" \8 O; X/ @: Q" Q7 s0 a8 z! J
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 l" R  K4 V/ ^. g0 i7 J7 ?- J
{
) v. S2 n& {  ]) Z# \        comp temp, xtimesy;

/ o1 ]& x: q* m! O! q4 f6 T4 z3 E$ u" v4 _6 K" @! R' x
这个不是这么比的吧。。。
" ~8 F* Z- M3 I2 T3 h' H4 ~4 Y2 }/ q4 e4 G% ?
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
+ U5 ?3 `& z- _& r$ W6 D0 ]8 z' |; X: e9 [# i1 W- b
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 6 |% Q, q; X  ?& |
数值分析 发表于 2022-9-25 00:20
7 ~" x) A! ^4 ?这个不是这么比的吧。。。7 k* v- H3 R. L- x0 P4 `5 _9 H

9 t( u; E# E/ t3 @' G' ~+ I# x您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
9 h" H5 `5 m( ]; D6 p, Y

6 W( {+ i6 m! B2 \1 \7 j! L3 V2 q有道理。
5 Z1 J% ?" l: ?所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
7 n5 E! H0 y% |: `4 T) C! A( \, t' _; a
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
6 U% Q" U7 g0 I) r' ]有道理。
* l: x' V$ r6 h- U  I所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

. x- _0 \3 m2 m你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
* q2 Y: L. u- J4 I; H; @3 ~4 xWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:208 ~0 G( K7 D4 G5 @  O0 t
这个不是这么比的吧。。。
# E% ?7 w9 [( G4 [- W
* O. s% P5 I2 D6 I  {1 g您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
  k3 R2 d2 D0 t2 }4 p! ], l% @

6 D( `1 I4 T6 P6 s9 b1 n6 {7 {现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
  N# ^- a0 J, i* [1 Z# x
沉宝 发表于 2022-9-25 01:48' q7 r2 j$ u$ @- I2 g
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
6 O" T2 F- N5 `2 \1 f: G" a# s

" W) c4 c. |& l0 G9 h  t. c是的,兄台说的对。1 I2 {8 j8 f9 H% m& h( u
) c  Z( g6 C. I8 B5 Q8 z2 K) M0 c
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
1 }4 `$ S$ r: `1 K$ D
$ n4 k# N* H! A- R6 \: V$ p, G雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
) e5 y! }7 k  {2 J* v
& R. {( e4 o6 x* C1 u比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
0 I* T  k& f. ~1 E% V# o- \' u+ I
  ?5 J1 i4 l# Z9 n% h0 U当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 + x0 J# K7 s2 B; R# r% L
沉宝 发表于 2022-9-25 01:27
& @; `8 ?3 h; ?3 `0 f( {# A你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

1 v: I4 F7 z/ g7 F- D0 T
3 N! Q. x* t. R# n' O) l4 h又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。  P! f9 `, O. J# [5 [
$ c; P* f; X4 i  u& G# a$ [
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
. M4 w+ S6 Q" t- r: F% L$ F' K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) m( M5 M4 W' @' l1 D
时间差一倍的结果可以接受。; e, u8 D7 ^! u6 b# z- l' [' A
/ T' U8 q8 \$ ^; \2 S8 s/ W2 ^
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 4 @* K2 D% d  j7 K3 o4 W  y  s
雷达 发表于 2022-9-25 04:47
( V8 v$ ?; A: {  |  |" z又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

" h% C* {/ ]3 d5 v( `2 |4 p; E
9 n9 ?8 D1 x0 L3 H/ R# I! N1 i! u; F' b& P7 `& E/ T/ c4 G" T' d

8 ~0 i  F! T% d+ W能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
, l1 A6 ~* o) g: @' \6 @" u/ S
数值分析 发表于 2022-9-25 14:58
/ }" x$ J/ |* _* `7 x: ?" B能不能把这个也贴上来,看看和上一个有什么不同?
7 [# }" K& p1 l
理了理思路,重新做了一个测试。
, m# `2 ~. }- j5 M3 n6 s做了两个 vector 和 两个 float *, 都长 100000" C+ f7 G! p0 e* |2 v
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.  P& U: E8 Y2 N/ n
1 M5 i+ |3 K2 d% M0 j
内循环试了4种方法,
* s% f4 e, ~5 \" d. R3 S1. 直接调用 vector inner_product 247s
/ J4 m6 u. D1 B7 v  Q2. vector 循环点乘累加 237s' |, D7 E. r& E) J0 n! h2 n; U4 H* Q
3. float * 循环点乘累加 204s4 A1 y4 m2 ~. D1 I( e' y
4. 空循环 100000 次 202s
8 [0 Z* ?2 O2 l! I1 l+ c
  n1 U' ^; z; Z+ h不做内循环 200s
9 W. L. ?. Q2 E7 U: B- s& A
. v% w# S8 p& e, A% q你昨天说的对,内循环本身占比是很小的,大头在其他处理。  Q9 w  K( r/ H+ L  y* L6 u
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
! k$ j% ]4 Y- z, w# w: i+ j2 [
- K& n, Z& k" H# u% h& i5 k- d9 e) L至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)4 E( Y2 {! n0 R5 g9 c' a+ R

2 v* g; n* X, c6 o- N' P(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
8 S5 ^* U; ], Z& {0 M1 _, v
6 K2 J. |  k7 x: H
        std::vector < float > vec1(N);  J- C0 H6 k8 _9 f. r( R1 i8 t
        std::vector < float > vec2(N);* B: O* k5 E/ k8 S
        float* b1 = new float[N];' f- B4 `, g; g0 N
        float* b2 = new float[N];
: G$ @+ O+ S( h. n/ r9 w
- K. `8 w4 d% O+ E% U: }$ X        for (int j = 0; j < 6000; j++)
, W$ J+ o+ _" ?4 j4 p        {& E, n5 J$ p" }  e  H* p# J- @
                std::generate(vec1.begin(), vec1.end(), []() {
3 z- g# r; j  r, [1 v4 J                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
0 R  r. M. _! }3 c                        });
+ g* Q6 k% a# Y4 Z  K
; |5 `, V. I/ Q& o5 V! p3 h2 p                std::generate(vec2.begin(), vec2.end(), []() {
9 \6 b, t+ ~, z. s, Y. u                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;) V- G0 y# m) k6 w; B  z
                        });$ S2 z+ a* n& [# [5 R* b) Q9 ~

1 {- w, ?) P  j" }5 O" D0 W                for (size_t jj = 0; jj < vec1.size(); jj++)! ~7 W1 a, S) K  M  J5 D" }
                {
4 U& g! J4 f! |4 t$ |# t7 d                        b1[jj] = vec1[jj];
) w! k4 ?, ^  t3 m' S4 F                }
) z. t  u/ ]. Y) G; n8 O1 T: B7 a1 e* A1 ^) I  S
                for (size_t jj = 0; jj < vec2.size(); jj++)1 h* t1 [! t, Y5 J8 A+ ^; _
                {
3 G) w5 i; B9 A. g1 j5 ?                        b2[jj] = vec2[jj];+ V' |) i9 V2 y0 h' e  }
                }
7 \3 l+ p  y. B3 Y* B9 y- k- A/ z: w2 O& c# n0 p
                //Method - 1  N=100000 247s  : X3 `. j* g$ p# G
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
3 m3 `  ?7 M" Y, X- ~& q  y, j3 F4 g                                
3 }0 k; H! ~" M; w- U                //Method - 2  N=100000  237s5 q( o3 P) j) g) w: ^
                /*
% g, ]5 M& P3 s9 Q( v. D                for (int jj = 0; jj < N ; jj++)
; T$ N& g% r" d+ ]8 e" j, H- S8 B' H                {
1 U& O' z0 W7 y                        fresult += vec1[jj] * vec2[jj];0 Y% O4 b) T, k# o5 t; _6 T
                }
1 t$ \. Z- v& E3 \: C                */
" n4 n9 l& f( O6 a2 p                                4 `, r: q; V' F! L( N+ K
                //Method - 3  N=100000 204s
4 {5 M! S7 k( L. T3 [# o" _: O                /*
4 r1 Z" {. }: P' v2 ]                for (int jj = 0; jj < N; jj++)$ R. k, V2 o  h1 U! Y* s1 p
                {# }5 A2 g  u& _+ k6 I
                        fresult += b1[jj] * b2[jj];- S4 I% v3 @$ y* |/ U" g
                }# [# @" M, ~2 H$ f) f' W8 F8 B5 n( {
                */' z; |4 |9 n! g1 I
& p- h: G. H' e; `# F( @. m
                //Method - 4   202s
: R. x% f9 b8 S3 h9 o7 Z. Y                /*  {, x. h. K& i
                for (int jj = 0; jj < N; jj++)9 B" E# B$ d0 Z! [1 K: ]
                {
# t+ |; q0 e9 U                        
& s0 T' b5 d, k                }
+ r) c- |' p8 J: z* d9 R                */* Z3 d. e- U- s4 X) F5 H
                //comment out all methods, N=100000  202s                7 k* B& O% h, T, N
        }
: `3 w) {9 R! r! N1 i$ l$ z$ p, A! m1 a: j4 J
        delete []b1;6 x% C; \' Q% ~8 A2 u( F& J; l
        delete []b2;
& u0 O) B9 D0 b# ?5 s

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' {7 h  d# G1 e3 ]6 L& ^+ P% Q$ h  B$ F& G/ O" Q6 U- w
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
9 y  R4 Y% ^: }. w  @* N8 T
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15! q% i5 b$ ]& Y* j) w! d3 }
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
. z, _$ g6 s1 D% n5 I, d$ C+ u
2 |: G8 B! r7 P% y6 _0 v8 q你第二个试验里面的j在循环里面又重新定义 ...

  {$ S1 Y6 l/ P内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
( d- D! e5 ^# M, x* ]
2 f7 x0 P" T. ^9 \+ W- O7 L+ `不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:160 H; R. o) j( d2 d6 h  q: |
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
" c5 Z2 U6 `8 e: L' u6 k
! A, D! v' d- M! P2 ]# P: f  I不和它 ...

* w, Q. {9 j0 h4 d2 G0 {0 \& g+ N4 |
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
/ X7 _2 L9 t! B6 Z后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:544 D# x! q  e7 g" {: |1 r
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
3 u( \0 C/ W6 r/ ]{
( Z' @. m& S6 a0 ?        comp temp, xtimesy;

( t2 Y3 ^4 w8 C: Z, s/ t4 K这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。( s: e; m# h: p4 a: Z- n" L
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
# T( C, ^  ?5 jVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30/ E/ L: N8 D5 Y  J$ s: {
理了理思路,重新做了一个测试。
1 g/ N; |# ], @# P( y- ]) i做了两个 vector 和 两个 float *, 都长 1000003 O( V  n' \7 J5 F0 l( d
外循环 6000,里面先做随 ...
! B$ {( S1 {" M4 J: [% g
这个时间是从哪里开始算的?
# j/ Q# O- ]' @我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。+ m! \# r, x& X: O+ g4 i9 t
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
) Z/ j+ W8 }! `这个时间是从哪里开始算的?" u. V) U$ v+ K2 c
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

, s2 _4 {2 a! @  U" x; k3 ?我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。, p- a0 p, S' _! S- E
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。) r- R/ `; ]* m# \' f9 d/ e
与此对应用数组(指针)花了2S+ ~. P7 w- Z) o+ O3 k" D' z2 {
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54! p* x8 R" T- k9 U
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)1 b0 q/ ]* d( s+ Q4 t
{
0 r9 g7 N( i8 {  q/ S        comp temp, xtimesy;

* H" E3 m- s' Y5 g" G5 p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
) ]$ Z) E3 `% r! |, `
6 N# A" r  I- M4 o1 V
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
$ ^6 A1 g3 @9 \我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% e+ k* [. c) A
1 ?. z- C; c: M3 w" F* n% u ...

$ x6 [7 V" M& D4 c你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。* F, u4 Q4 j" W4 C6 l) n9 |* g

- U8 d3 b& ?: o& ]( m雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 + O$ W0 ~( Z. H5 C8 o6 \
6 ~7 V2 Z) O+ l( O8 L( J3 W. Q+ R
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。; J+ x& x# E/ m+ U
有空时我会试试 SIMD和并行,看看能提高多少。5 ~" z9 W4 n3 f4 G* T$ x/ \
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ( }: {* q3 H0 Z" }
谢谢大家的讨论,I learded a lot.  红包已发  ) M# N# X3 }" `
$ p% G1 C" Q0 ?3 V

, @# S  i: }. z1 Y: z
: b0 t# N2 k' b. h+ O1 x& C% W8 q/ N7 C  q  V+ Z* ~- ^) p





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