爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?: j9 E8 x. w9 D. d! A1 s

, c* P% \! p, J. r4 [3 W3 i2 O自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。( u) k3 W9 l" v, P, _' ^

/ [2 u3 v" [# j: M1 m" H; u速度优化问题真的很有意思啊。
2 z) i6 I  P+ I' x& S6 T; s: g
6 H2 w4 Y  X; q% h6 K! g% K( H欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
" q0 H1 U: N9 p* N" \/ a& U把代码贴上来看看?
$ k* ?; G( H+ T' L5 S$ t4 j  }( R, C' L4 ~& t) l
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 6 G8 Z' d% c2 |' e& S8 W
数值分析 发表于 2022-9-24 23:042 O% l; V& V$ V$ h3 [# X1 V, j
拉下来?拉多少?4 a. q) Z& K4 _% K
把代码贴上来看看?
$ d1 a; l+ h9 g: J9 I0 x
: \( C9 S) s% C
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 W- ^, M2 D+ V; x; j* `' S
{; a3 M1 s/ [8 |$ r3 F2 p8 }+ j, ^
        comp temp, xtimesy;
9 W+ r& A& A5 z. `! x0 `        xtimesy.re = 0;) D% q6 Q' w) I2 A* Q# k- x$ ]
        xtimesy.im = 0;7 H4 D+ D1 C& U' X) p
        int j0 = lenB - 1;# |- A* _. n# C
        int    i, j, i1, reali;
' r6 N% M6 b1 P7 X! \        if (lenA % 2 == 1): x5 U) p, W+ E  n
                reali = lenA + 1;
! F8 t2 H+ ?, Y6 B5 q4 r        else7 j  j9 `( ]1 y9 |& v
                reali = lenA;# e. d, `' W8 |0 P) u3 g  j
        reali /= 2;, @1 I0 ^+ }5 t9 e

% i$ s9 V) J# R- ]% k% {& l        int nconv = reali + lenB;
% N0 m& @, v% W# i/ k$ L        //#pragma omp parallel for
# F5 i  |. x; X; g" {$ ]        for (i = reali; i < nconv; i++): L( P  V; h+ `8 x: _5 f$ p
        {
) y. @5 u1 ]5 F' X- c1 ~                temp.re = 0;+ x3 s# ]7 u9 v+ L& d5 L
                temp.im = 0;
% q/ ]. z# r$ ~  I6 u& d                i1 = i;' x, M" `( \& E  s7 s
                for (j = j0; j >= 0; j--)2 f$ j4 Y, `) ]: K: u
                {
" V) L  k; d3 W9 U* T/ C% e                        /* floating date operation */# [6 y2 f  Z8 p; e
                }

: P: c6 F3 C" x' h9 l        }
% Y- p8 x* m2 O}
  {4 i, k5 N, }% D" ~
- h3 s8 d6 ?) b2 ^' s& hxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
- z7 n9 N1 p* F5 T4 I: V7 g$ u
$ |) b3 Q  d$ l0 z# A红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
2 k4 Y( V) ?, }% }# }) ?* V现在call xcorr 100次,耗时78s.! G: Y3 [2 v& i9 t4 `

5 @! C) @+ A9 _3 a如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
# E6 O& O+ j# p% t: q7 g
0 h8 U3 w& i9 ?) w
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33; c* U6 v1 V/ {1 X1 d0 ~* {5 S/ e
Maybe Debug mode?

! q( y& \& q9 R, L+ r5 A$ S+ }1 ~2 h' _
不应该,看我上面的回复。
! Z" f4 r0 P/ a- B. \: M% t" ^
- X+ @- E4 A/ r# h0 L6 s! ]  E我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
% Y3 p5 n, O6 G; {  |4 ~1 Q
雷达 发表于 2022-9-24 23:54
- U- L# i& A0 R% q$ A% T2 C4 uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
: f5 Q9 a" Y3 B- s4 ^* N' Z, ]{
, T; ~' x. \0 t, u2 S9 C        comp temp, xtimesy;

: j! y$ b. W  C8 A: H* \6 Z
6 ^9 ?" ~& S% i这个不是这么比的吧。。。$ \! y, a& S3 J, v* A! S. W
& I- r* g: h' N0 Q) n1 S: I, G- F
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
, F: d  q# m  s
  O' T# _/ \' B6 C6 G' x, t' c! q而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
1 o" _2 x; `2 H, V
数值分析 发表于 2022-9-25 00:20
0 _# j' }; t  q9 ], O7 Z: m8 w这个不是这么比的吧。。。& W# d1 r* a1 E8 u6 `! [
, T! q+ P) f" l* e, J
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
4 K, {+ y6 i: P2 s% b4 E

3 D' i+ J  C% k7 t2 f* |; U有道理。1 }% Y7 C, V6 |/ u; ]% o0 H
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
& v+ e$ C, ?  R: I5 v6 @8 k4 S9 k1 y; P
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46' w- |, j. Y* O$ P! [
有道理。$ p' c9 u4 K% ^' F# c/ j7 J
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

8 G! Y2 n+ C! V! K8 D1 U你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多- P- X% R; R: E' @. B
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20. P' |. z9 n4 B8 s- ^
这个不是这么比的吧。。。# L2 L" E& W  v. V; E3 i; K- ^

- i: F8 T3 J1 r) a# k/ ~您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
2 Q1 w* K0 P- g1 w+ [
1 Z$ N+ S8 J2 u( Z" [5 @9 g
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 ' f% |9 V! q4 q2 e+ M- K# }5 d
沉宝 发表于 2022-9-25 01:48! j, a7 a" d. {; b
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
5 K4 Q3 y, B. \8 j* u
& k; H( ?! P" u6 q: |+ {
是的,兄台说的对。! R9 F1 l0 G$ }( M+ B) D) ~
% N6 ~  H9 K& R4 F0 `
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。8 ?5 F( y) h( Z5 J
6 x  O  h  W7 x* j, K2 Z
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
! _. Q/ T; Z* E: {6 w8 B0 A7 ~- V' E: j! j: y! @1 {$ G, W
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
- p! c$ J$ w, Q4 }3 y- J3 i7 l1 U" Q; A. v
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 % x( W6 b' W4 f5 ~
沉宝 发表于 2022-9-25 01:274 F2 B. m0 n, N* s  O' m
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

* Z6 T6 E! Z8 Z. W: q, v4 q8 K0 G, |
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。' N5 `4 x* {: Q2 j9 ^& w
5 g" e2 {# R, j0 X& `
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
& ]! Y2 D9 d3 l) _- e2 z( @% F! h又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, ]4 G4 A" B, ^3 F5 D+ `6 r时间差一倍的结果可以接受。
1 [9 s" {0 {4 E* x/ o7 C' k* [# N' `4 R9 b
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
. t* h; C' V: u; j; P# b
雷达 发表于 2022-9-25 04:47+ ~5 ^- c8 b( w6 G  i8 W
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
0 ?3 [) B* |4 ~

8 }# N; i  x3 H5 s0 q7 @8 A
8 u2 b6 ^, i* u# \7 ^. K' W
8 S9 r% t0 m4 {) C; F- Z5 V* n; U能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
2 w* i, ^# ]( ]
数值分析 发表于 2022-9-25 14:58
$ l( i# w0 g, X. h能不能把这个也贴上来,看看和上一个有什么不同?

" H4 P) a3 {4 L5 `" q+ c4 Q理了理思路,重新做了一个测试。
  f) w# X( v: B# J! f. }$ V9 N7 f做了两个 vector 和 两个 float *, 都长 100000
8 z0 S* {( s+ F, o1 h  K外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
. d9 I5 U; H; F8 r; d' C( _" l. S- c+ C7 p
内循环试了4种方法,  b! [% p0 Q5 C& B1 ~( g
1. 直接调用 vector inner_product 247s - v, H/ V! y; \2 z
2. vector 循环点乘累加 237s
0 n) ]9 y' E7 J3. float * 循环点乘累加 204s% q, c' m; u* ?% ^1 n6 k
4. 空循环 100000 次 202s
1 m1 L+ S: P4 b! R7 c  T, j, @# s# N* l8 @  j
不做内循环 200s
9 E7 d8 g0 P2 S' o% B5 s. R! Q/ {
8 K) R. {, H* p" n/ U你昨天说的对,内循环本身占比是很小的,大头在其他处理。
- v2 H& s/ |/ C$ J4 z另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。, V% Q8 x6 u# r  n, c5 I
) D- S2 R/ g( K
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)! o0 {1 c( R2 K3 R# a, M( P! S
9 h, w3 ^9 Z  q- b: K8 \2 u1 F
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL): Q$ N. C0 Q/ i* ]# ~& j$ I' d  S: _

9 H* T6 I" c" A
        std::vector < float > vec1(N);( y0 `, \/ O- F- J5 L% Z
        std::vector < float > vec2(N);
/ l8 n: U4 h. t( L! F7 E# V( W        float* b1 = new float[N];
: A3 ?/ J1 o9 k, Y9 Y* Q2 n9 K        float* b2 = new float[N];( z# L; {) F5 V

5 j8 G& \; P8 @/ Z  P6 y        for (int j = 0; j < 6000; j++)# v/ x, E: z" F. {4 v/ B
        {
, ?2 ~' H1 I4 N4 }                std::generate(vec1.begin(), vec1.end(), []() {0 e  f0 l8 l3 B# J9 p
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
3 |# w6 Y- {; }                        });( }1 Y; J; v6 a) S

0 P- o) ?6 I/ a# t7 ~                std::generate(vec2.begin(), vec2.end(), []() {8 I0 w# o- Y) k
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
# S! H. M7 G1 z4 {4 c/ C                        });3 P' j& ]" J1 w1 n

2 r1 W1 q5 K5 ~3 s8 X+ p                for (size_t jj = 0; jj < vec1.size(); jj++)
, h7 K, ^- E0 K+ t6 K) \5 r                {
- v/ R. ?1 Q* E7 w                        b1[jj] = vec1[jj];! j! N! ^( f: s4 O+ a( B
                }
2 F9 f! i0 v1 k# Y
  o% r5 m4 _2 O2 a2 h                for (size_t jj = 0; jj < vec2.size(); jj++)( J. X, ^9 z( P
                {9 |, k4 [1 L, A
                        b2[jj] = vec2[jj];
! {1 j- Q- S4 d$ u) X3 ]                }8 W/ z- w( P! s. i5 G
8 _. V) W, }% ?$ t: r, T6 L1 M0 X/ `
                //Method - 1  N=100000 247s  
. |  v6 |! q& o                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);* Z% t2 R8 A3 @5 Y7 U
                                
* `/ t1 ~" L. s- r4 w                //Method - 2  N=100000  237s: R* n% s& X( k3 E* c* P
                /*& C$ |( U0 ]% X6 L) G
                for (int jj = 0; jj < N ; jj++)1 N, A% U0 K( w6 N7 s* C+ x
                {) l6 k0 C7 e+ _) ?3 ^- @
                        fresult += vec1[jj] * vec2[jj];- w  `2 u, \8 [2 m
                }1 X% K; A0 O- s- V! ^) [* P
                */. N# V) o3 Z4 Z4 ?: y, ]* U: }* m
                                
2 M3 ]2 F7 l, l: l                //Method - 3  N=100000 204s
( w3 ^' n( ~. c: t1 o7 A6 z) p# T, a                /*" V; J7 N  k' k" _+ T9 P5 k& j7 H
                for (int jj = 0; jj < N; jj++)$ g/ _0 d, I; R1 K8 T/ o' Q
                {
) h$ K  i* Q3 \, n. A' Z                        fresult += b1[jj] * b2[jj];' z3 ?) ?( T2 J( w3 k2 H+ }
                }' U+ ]1 K/ J- C# B! k
                */
- }' q: T2 M8 R% X7 V" E7 c3 C* n' d$ _3 R  z$ w( u* r
                //Method - 4   202s
8 T1 r, d( ^: p5 N5 C2 Z                /*0 _3 ]5 O4 g+ S7 E4 C' ?
                for (int jj = 0; jj < N; jj++)4 G/ `% h* l5 s$ L
                {+ X9 [+ x- ]! `8 T
                        
( `- f  e/ @2 k" K6 T$ j                }, Y3 p9 o5 `( M1 Y: y
                */
$ M9 O1 h/ @2 f9 \- R! q                //comment out all methods, N=100000  202s                2 P1 ~, s: }% h, o& [- F
        }
! }+ P4 p* d3 y4 X0 U( V0 w" \, D3 H# ~( c: h
        delete []b1;
, |' H% f7 w- Z/ [3 U        delete []b2;
9 p4 E0 }3 u1 e6 c

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?( D7 j5 a# C# p3 [8 p( Z6 }2 F) }
% ]  d4 e# x- @; z/ ~" T& n
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
) H; Z& P$ u, ~. ^, X
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:158 b5 p8 }# b% w
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
- S$ t4 w% ~$ K; d) ?, H0 I8 z
5 ?4 d! G8 O6 p- |  K1 o+ L7 }你第二个试验里面的j在循环里面又重新定义 ...
9 T7 c$ f4 Y2 h) \( b! b7 S
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
3 `; c" I9 y  @; D5 R2 d8 D# c+ e- E
& x, v( s) @0 @5 [6 `9 Y' Y6 I不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16+ t2 M$ K/ ?5 [) H
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) K1 i5 u# S( m2 J. C

5 |, I0 i- P9 m( c+ I1 Q7 Z# s3 B) C不和它 ...

+ S1 X6 Q% d$ j+ ?, _6 R  J  l* W, u$ K% e5 @- ^
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。* ~' P& {  C: `' G8 }* ?
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54# ~& J6 {3 E0 J6 w' z& M/ }; H0 l
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
/ Q9 R" @3 k: s! A0 ?{1 F! J6 c* n: C0 ?
        comp temp, xtimesy;

- r  x' s2 E! _& N. o0 O这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。8 T9 F. @* \5 u) R' d0 R8 t
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
/ G+ B9 p6 U2 U+ e7 F5 K/ HVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
# W8 V1 R  C& j( n理了理思路,重新做了一个测试。2 T! \# W; Q5 N" @/ {
做了两个 vector 和 两个 float *, 都长 100000" k. u  F- B2 `2 ^! q
外循环 6000,里面先做随 ...

& k( ]5 d: M+ ^6 n1 Z6 t% P这个时间是从哪里开始算的?
  z9 l+ @% L6 d* [) _2 W我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。& [8 I$ ^1 e0 y! Z7 D
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
2 n" l4 P3 i1 }# z1 @( ?: m& B. V这个时间是从哪里开始算的?
1 b  M: G# X1 |  X7 N+ G我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
, U- ^% ]0 E( O- _6 y
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。1 ^0 G+ m5 y2 a% k/ w0 \
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。) M9 y+ X2 a  n6 Q  q. O) Q8 o' J
与此对应用数组(指针)花了2S3 y. f" n) }  ]$ E
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54( k5 _4 I0 C4 R; u% X7 X
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)4 F  Q: ], D! e+ A
{, I" M& K! m3 {; L' T: j
        comp temp, xtimesy;
/ g% p" v0 w5 V/ q! r/ Y9 ?
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗) v4 f* L! L; k. L) X
, v, _" K# @  m

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29! O- U# a; p) H
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗" x( ^2 }1 @+ q. [

0 f2 J2 T- Z) [' Z" o7 C3 Z* b ...
9 U0 J5 f  U" ~, w
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
- g( h5 M' `- Y9 u. t' p, b) q& p1 n2 i2 Q; X$ Q
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 + j4 o' h4 F& G$ U

. W; j3 P. x1 o* @0 q" v是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
) S' i6 [1 Q3 y有空时我会试试 SIMD和并行,看看能提高多少。
' u2 _9 I# @$ W; k8 s$ j过去7、8 年没有正经用C++ 写过东西,没有 sense 了
% Q, s( |. z) N7 y, O谢谢大家的讨论,I learded a lot.  红包已发  
$ p9 e" u/ k  v8 X1 [8 i1 n7 v- ]1 A
) c& L8 k2 h0 J! T# \9 L+ X
7 e$ _& M- t! C$ D. d- O4 H  y; @& Q/ |; H( p

# F: ]5 k) O( U. M! q




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