爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?4 {3 y& U# }& `/ U
# \) O9 H; v! [4 H2 ~
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。  U  R+ r. g* N3 n' b) b: Q
" Z- x6 l% ~$ \# [
速度优化问题真的很有意思啊。
' @+ ^5 m( l& \' P7 F4 L3 J% I6 V# V- |
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
: ]: r- S! z3 K0 h- j把代码贴上来看看?) p! o# N# x; }& h0 S/ E/ N  }2 T% n

8 W# Z1 c: K; Q+ ]  ]难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 5 L) r2 g0 D, f0 L% L$ _2 W( B1 }6 p
数值分析 发表于 2022-9-24 23:04
4 R- {% C$ u1 i9 v2 x2 N拉下来?拉多少?
( E  W  f. P. p把代码贴上来看看?

7 T" d7 G! y9 O1 n7 i2 b  |% S# b! H: {8 U! ^' `" O. l- i
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 w( w4 T! [: L* O% S% @( w" Q/ g
{
5 E# I. p$ G  \8 c9 w9 I5 O        comp temp, xtimesy;
/ w# o( `" t4 y4 J8 W        xtimesy.re = 0;+ u; C; k# D1 O  n! N
        xtimesy.im = 0;) P2 j: ?$ h4 F+ D3 ?% G0 \
        int j0 = lenB - 1;5 X& l/ B3 s5 m( }8 v7 M4 Y! E6 g7 K
        int    i, j, i1, reali;' m: {7 j1 _9 [4 y6 s+ H
        if (lenA % 2 == 1), @3 b; n# j& A
                reali = lenA + 1;
' P  _2 V% q( z* r        else) ~* H. I# B3 i  o$ m
                reali = lenA;
2 {+ {1 ^0 @  Z, n; d        reali /= 2;
8 b' c$ T, U1 t- R- I( P$ r5 E4 H6 ~% `1 W0 I
        int nconv = reali + lenB;
7 C1 ~" `& L$ E/ P& f  T        //#pragma omp parallel for
. `' o. Q( X" ^+ S% J: C        for (i = reali; i < nconv; i++): }5 o# }+ J" i( v9 G
        {3 D% H, U& T+ t" v" n
                temp.re = 0;
! x+ k9 I5 z  r! J9 C                temp.im = 0;( r0 A" t% W/ W3 A- ~1 b
                i1 = i;$ a, O: ]6 x! q9 e# |
                for (j = j0; j >= 0; j--)
  r& g8 C. N/ M. A( e                {7 J: L. h; K7 B( e7 ?& a$ S; ?
                        /* floating date operation */3 ^& Q# @3 q. z% U
                }

1 f/ O$ _* {! L! C& `& ?  K: g! p        }
5 Y$ ?$ P9 a/ ]1 @}
, Q* |% j5 J& N( ^: Z) i0 C$ b" V; [9 r& H
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样! b$ @( }% \# f* f; c6 s

- P& v( s8 y- G/ a( ?$ b: O/ u红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
  T* N) l  q! p; D现在call xcorr 100次,耗时78s.7 \7 N. |# W+ ~! f3 U  d+ V" T: ?' C

0 I) b& D0 b3 e' b% t; ]* H如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 9 s( J8 Y4 S8 v. y' i: T0 L2 n' h' U( _

& C8 a% A1 Y) W+ h, t: a
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:332 \& w8 n' Y5 A# ?2 W
Maybe Debug mode?

+ q) f5 r% R1 B! K" ]: z1 A
7 d$ Z3 s: ?* e" G4 y  N5 F不应该,看我上面的回复。/ T0 }, q, D+ f  y% n& W

% \1 ^, {! @( s/ l& q: J我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
8 M* F2 `" e0 }, h2 u7 o
雷达 发表于 2022-9-24 23:541 }0 N! V5 G! ]; }
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  r( v  w+ p% Y$ K{/ ~3 i% E7 {3 j2 u0 a: h$ q9 o4 m
        comp temp, xtimesy;

8 E+ G1 m" `  V, \5 |
8 ?, x' o" S1 \; L, z: t. [9 E这个不是这么比的吧。。。9 S) n* D) X- v' G' \
, m/ C0 j  C0 j8 |, l7 V
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' K: A7 ^  [3 X4 D
( `% L  b0 a% @( d! [而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 2 x, U- C7 A, R, }$ p
数值分析 发表于 2022-9-25 00:20
- U( k% B: ^  f" `2 ?$ t这个不是这么比的吧。。。7 U; E5 m! V7 O% y( \

; Z% n: t. X- Z; t" [( @- z3 {您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
# T: _' g  C" z; ^; X! y

3 U' V" H! k1 \' _) n$ J' v* D有道理。
3 Q+ S7 a7 L" ^9 v5 a( e所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
$ l$ l( O% n$ I  N
3 g4 U  ^: X( r' i; V我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
$ ^( D5 Q7 ?' U有道理。/ H1 A5 F9 |& j4 M6 |) q2 o" u
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

6 Y  E* q) e" Y你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多8 Z  F( s: ^$ M1 Q
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
0 L! D% ^1 U" w' ^2 ]  b这个不是这么比的吧。。。9 i0 [" ]+ w5 U, w, \; M
8 Z' s/ T* N$ _$ k
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

8 N$ P- \: Z' y0 `6 _" A1 i& X& k2 g. i/ K
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
: Z" y2 S$ Y- P
沉宝 发表于 2022-9-25 01:48% f! t4 R$ x% [! X) `( U2 }
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

# O0 G, n! E+ R- |6 O0 M
: G6 d; X9 f+ B- w9 W是的,兄台说的对。
6 {9 W: ~# x# S1 k1 o+ o2 v$ ?: @" m  b% }. \0 L
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
# w5 r( x; s$ ^: o  A: r/ L+ H) s# ]6 x* X+ f- Q
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。# E& c  K- p$ \5 I6 _  @6 M
8 C% m2 c" O3 h# G9 a! w% }- d9 I
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。# J9 _  V/ C5 u4 W
/ j) u6 t" C0 ]& x
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
6 }$ i; b4 Y; l
沉宝 发表于 2022-9-25 01:27
  ]6 l/ B$ ?, ~' m: L1 Z你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

2 W& Y( w& I2 T' [# Q+ c% t7 e- ~4 X0 N/ W! O  \4 D6 j; l
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
2 C8 E; M! H8 j5 O
7 y# L7 M& b6 `0 c# v3 V: E1 `我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
2 Y5 n& }( x% k  C1 b又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, [3 q" q, i4 x) f' n时间差一倍的结果可以接受。0 r% Z+ }" M1 k+ {8 d* U, V5 a
: v4 S1 a/ |$ |9 p! O* D
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 2 ]% m/ N1 ]$ b5 b- [
雷达 发表于 2022-9-25 04:47! V, B: S2 o/ N" Z+ g) r
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

3 v# G: G) F' s7 c. P  v! r+ J, A
% l- a, U' n$ D! u) O
5 v1 W) h  F1 [0 l3 y8 a) j7 Q+ k6 r
  `% S0 ^8 g" ?" n; q能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
# E9 n! F# L) s2 Z
数值分析 发表于 2022-9-25 14:58
: a( y+ y3 v/ C4 U能不能把这个也贴上来,看看和上一个有什么不同?
9 X$ Z/ x6 `# z: C
理了理思路,重新做了一个测试。6 h# ~: P- D+ M! R
做了两个 vector 和 两个 float *, 都长 100000' J9 N, p/ [- F6 k8 P
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.' B$ ^  z8 P  O1 @6 K% B* L) g
) k( a+ c# `; r! o, V2 [
内循环试了4种方法,
1 p3 m! }# q: U1 M1 V1. 直接调用 vector inner_product 247s
/ ^. p) u  s& U4 C% ~! r3 ]2. vector 循环点乘累加 237s
6 W: R, C! U9 [, w& Q3. float * 循环点乘累加 204s3 @- C1 d, h5 S( x5 I1 Z9 l
4. 空循环 100000 次 202s
3 G6 T- v9 R7 x5 ?( S
& C  b! u2 N% T# b不做内循环 200s
0 D0 ?5 F% d9 a' K. F; O% S5 V! f3 u: g/ B7 L4 }* M
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
5 P* o  _5 H; G6 |& X# X; B8 H另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
. ], ]/ i; F) {6 _% t
. D' @6 Q% V; E: R' ~/ X0 ~至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
  U; ]/ d/ M' t* `8 U* C3 b; }. J! i! A6 q  y" G
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
  C/ n" W  b6 u$ Q( |% n/ C* H! q' \4 }$ J
        std::vector < float > vec1(N);
/ a# |2 ?# ]. H: H4 x1 `# b0 y' W        std::vector < float > vec2(N);
# _( U4 Q1 |3 J0 N* [& t; E1 A: `        float* b1 = new float[N];5 U7 \2 a5 e9 ^" T
        float* b2 = new float[N];6 Y2 s8 _0 h7 K$ n, h2 Y
  k+ Z! v8 k/ [6 D) t' f
        for (int j = 0; j < 6000; j++): U, M5 y* K9 N1 k/ [
        {# ?, O% X6 b& M3 w) G3 Z4 L! {0 A& x
                std::generate(vec1.begin(), vec1.end(), []() {
/ d/ ~6 C' j) |1 E) j6 U& w4 z                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
$ K9 X3 r% d; K+ ?) O                        });
- M5 g8 E& w, f* J9 v
" V  r: F$ b' i, _4 z% e                std::generate(vec2.begin(), vec2.end(), []() {: F/ E2 `2 K6 X: |
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
6 a. S3 M0 Y7 i7 S! z- i                        });
9 j  l% v, ]- }3 n7 n0 g; x0 c, [3 N9 z) D2 @6 O  o; U
                for (size_t jj = 0; jj < vec1.size(); jj++)
/ D) f( v& k7 a5 X) _                {
" u4 t, g! n& m6 m                        b1[jj] = vec1[jj];
. ]$ \: B, J  Z% a0 z9 h* N                }
5 ^0 p9 f" `8 Y  x6 y% C3 e  ]* B2 A1 f
                for (size_t jj = 0; jj < vec2.size(); jj++)* x/ E2 K! a+ I9 r# F# Y. k1 A
                {
3 t" u/ A" n+ s) L5 D0 n8 w6 y                        b2[jj] = vec2[jj];
( i. `$ M: Q# M/ p                }
' p, i% V+ ]! q+ S9 G2 v. ~  w  }5 x1 G& h; v
                //Method - 1  N=100000 247s  
9 B" S4 s3 n" r6 P                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);2 F6 I! _) Z  J0 m
                                ! Z9 x; q7 v5 a! M: i: I
                //Method - 2  N=100000  237s
" W3 a; B3 \8 P' M. j5 x+ \                /*
4 v) Q( U% l& q( S( S. e                for (int jj = 0; jj < N ; jj++)
: e9 E# x9 A1 }( k                {
0 \1 R( u  g* T. Z' I# t2 a                        fresult += vec1[jj] * vec2[jj];
9 t& H0 d8 {$ j9 k                }
3 ^& p$ S, I# {- l                */3 o9 d2 F- {  a; h# E
                                % w# J/ r# T3 K0 a- m* W0 e( s- K
                //Method - 3  N=100000 204s4 L4 x( I( E" i4 n4 X6 o/ J% @; j
                /*
+ I. V( `4 e5 l0 ~                for (int jj = 0; jj < N; jj++)
+ \6 T/ ]$ z; {; w6 K) [; }                {
0 B; M# e& l0 H, \2 r0 z                        fresult += b1[jj] * b2[jj];
0 C% \, H8 y! o                }7 }, h9 H+ X! [' y; i2 ]6 c& y
                */
- B8 ~' F8 j  L$ c+ f
+ W7 S7 W: k% _( {* Q: s+ I                //Method - 4   202s
, c- q/ N3 X) S3 w                /*1 L- M- F4 m. k! P) L/ N
                for (int jj = 0; jj < N; jj++)
! k8 [3 f; N2 |                {3 m% p" C, p* q" c$ X9 f6 \! y
                        
! B3 y  {, \7 h8 K; h1 N6 {                }
( W% U9 _3 v9 |0 Z                */
4 N$ c% F: t0 f5 x$ u9 c5 k9 Z                //comment out all methods, N=100000  202s               
) V; s( ~2 ~2 ]7 r        }
, V* D% `: w! u$ s# v% s3 p$ V% f4 ~8 t0 m
        delete []b1;0 h' ^) u) r) [6 ?  v
        delete []b2;
, n$ g, d& B$ C3 y

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
& N' V; D- ~. z1 W; Y3 m/ T$ ?8 ?7 o! h7 V8 F8 N  D' h9 P8 U: ?
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?3 n  J6 }3 X6 r4 m5 g

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
) e9 P3 N. S9 V7 Q' b" o% C9 b5 m瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?9 t! C/ ?. j: G
  P1 N2 ]5 I) [  n! g8 ]
你第二个试验里面的j在循环里面又重新定义 ...
) v+ ]' M6 A" ~8 n# i
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
3 o2 L2 F9 ?5 r0 W
$ ^6 l9 V5 P7 ?7 C/ v* G. B不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:161 Y& C4 L0 X" f( B3 J' _1 x9 j
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
3 R: s0 s+ D' ^2 g7 ~+ v' Q9 x+ C- t* e6 }( b/ e
不和它 ...

! q( h3 ]) {6 [* S* ~( ~+ c- H
, Y6 b  R$ a0 y. c) N' B! C不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。3 t! x. \5 O" Z; ^; F& p3 N; Z* y$ h
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54, J6 z- c; g0 v4 |: ^8 S8 j$ I
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 R' a1 |9 @3 w) `{  o  e' C; l: X9 Q- @6 t
        comp temp, xtimesy;

6 ~0 K7 i( f; {' `8 G' O6 P' L- d这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。& }3 u- ?+ Z7 z- b% d+ z5 |3 a" M
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?" Q9 D. E/ L3 t% j9 _# n
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
, T+ ?2 p9 G) z5 Q  p# L3 e理了理思路,重新做了一个测试。; o4 j  @% o3 N- S
做了两个 vector 和 两个 float *, 都长 1000006 j, T  l4 v5 _8 w4 S/ Q* V
外循环 6000,里面先做随 ...
8 @) @* v9 `+ P1 Z
这个时间是从哪里开始算的?
3 @! b9 \# l3 u6 n) ]3 y* ~我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。1 s8 }* ^7 A# t" ?4 _
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39# K  U# t0 r6 m& e; _. N
这个时间是从哪里开始算的?; V" J: s: s* [( E0 y! s- x
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

7 c. j+ j, o, v' I9 t2 |我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。& F/ P* o( S, {( A. w
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
" b) l, I1 g4 u# ~7 J与此对应用数组(指针)花了2S8 D% f1 U4 }: ]& s% n5 E
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54) y; }( F4 j  c3 x! E- }/ v9 |
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
6 h3 E1 o" c: W# R% [; X{
1 _1 y# q( i0 ?- C3 i        comp temp, xtimesy;

1 j1 G* n7 K  i- I! x+ \1 H0 m我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗, _4 }& ^: V/ N% b

: k, Z+ Y7 e) p
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29' n' X0 h1 f6 N8 F' J3 R/ z/ H
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗  I; J8 ^/ n1 f" Q2 ?
$ ~8 s+ l4 w; y* {& P" a4 _
...
% M- U% D- ^/ I* |- h+ w
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
/ J; P* j, Z2 e/ z: G7 T1 w6 B  v; t9 c  E% Y
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 1 v9 \, Z" k, e6 T! U9 S% C
6 a+ l; t# E, C4 d' b& d* s  X
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。; J) E  ~1 \& N0 R, {; D9 T& U
有空时我会试试 SIMD和并行,看看能提高多少。" r9 w/ G' V+ G* I: j
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 1 i) J$ Y% k7 ^% K
谢谢大家的讨论,I learded a lot.  红包已发  
" q- o7 s+ G& g: {& D% `2 j/ K- k" r9 |2 r) ^2 [

8 v+ F3 ?  r) `; W2 L7 ~
  {+ I) Y+ i3 y1 D4 l8 X2 C! k, g  ]0 E# n





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