爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?7 @5 K( A% V6 `! e
+ o9 w" O- W& V( \. Q
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
9 P, P" T) \* Y- F* I+ j
+ \# Q$ b- F# \6 H# N3 a速度优化问题真的很有意思啊。/ `' Y% z( \) [7 q9 u% n& V

' i3 n$ _+ B$ O; f9 p1 t欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?" ^5 F$ ]9 J0 a3 q
把代码贴上来看看?
9 y+ y3 |! A5 l1 E  a) |1 Y- t
7 w3 y/ C; i) h难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 , |1 B  U" g; [  G
数值分析 发表于 2022-9-24 23:04
) Y( m4 T& {% {, Y. y5 c! e- E, c拉下来?拉多少?/ d3 V' Z9 }0 W/ s3 }' t0 q
把代码贴上来看看?

$ I4 h: y- h1 s6 B# i( m
/ D( U5 C0 x- Y" ^void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' O) O  ?; m% f2 [  I{3 Y/ V; Y7 b: [1 y  K8 ~2 I) g
        comp temp, xtimesy;
8 y: y  k0 Q; e4 t- n        xtimesy.re = 0;
3 p# Y+ m5 t0 `0 i- I* w        xtimesy.im = 0;& ~4 R% g; l0 e# A; f9 y: A
        int j0 = lenB - 1;& M7 v6 ^0 g/ z  M/ x' c
        int    i, j, i1, reali;7 j/ L1 W* P7 L# Q9 W3 E7 p
        if (lenA % 2 == 1)% a/ C! J8 R- Q
                reali = lenA + 1;
8 l. w. c  B7 U. p4 h        else
& q' b2 ~2 a+ d4 o5 N7 Z7 Q                reali = lenA;
: g- N3 a7 N8 ^        reali /= 2;
: a  B. Q( I$ R+ B5 a, T- F0 V3 z+ r7 A2 ^4 F: f: p1 a
        int nconv = reali + lenB;8 r. r' B+ V. Q! D# q5 u. Z4 r7 K# ]7 U
        //#pragma omp parallel for$ x, X: F; K1 T" c6 _3 y+ u) ^
        for (i = reali; i < nconv; i++)
7 ]) A' i; y4 e- A, L+ B        {4 U' f, c' B+ `& P
                temp.re = 0;
4 y) I" ^" f+ y3 L                temp.im = 0;
# q+ ?2 f; A- C# F                i1 = i;9 @# I  ]* n8 g/ k* n2 G9 L
                for (j = j0; j >= 0; j--)6 H  ?6 k5 @; \* x% @
                {) @- |; i# L" x% O; B' K6 y
                        /* floating date operation */( B8 P4 U4 N( @4 [/ K  p* ?0 Q
                }
/ x7 {7 f' ]6 E! b7 f
        }6 ~" i) C' P: F
}
& n) {, K$ |4 u& ^5 `6 f# S7 q; ]  e/ _% z
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样6 F! \) `& Q* k1 y2 _/ F9 S6 d! @( z

, p7 I' h" ?4 Y4 u5 E# l红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
; p5 G. A/ A; q现在call xcorr 100次,耗时78s.. u/ T0 j, i' k& q) `$ w

, S' S4 `5 Y+ u# V2 {如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ; |7 X  i: F+ `3 P

. X* l7 Y+ b( h% Q0 Z4 @+ M1 d
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33  S$ Y& d- ]! b! R: w; X
Maybe Debug mode?

1 {- P) n. N1 ]9 K: A$ O
3 ?8 a! o. c6 C  g4 U不应该,看我上面的回复。0 M+ N6 ^+ e  }- g$ i

9 K8 V: W1 P) J4 R; E* y/ Z我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
% V( F' f( n  |, @/ O
雷达 发表于 2022-9-24 23:54( E7 e* ?& U& R' |* a
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)/ X( n( S( ~( d: v3 l% C! }" y
{
8 i& ^/ W  o4 ]& b- `        comp temp, xtimesy;
1 F; |/ u4 J$ i- S# ~

5 ^; a" I+ U7 \" V这个不是这么比的吧。。。
& Z" h* E& S8 G# {( k
! D9 L, c9 V: P8 p7 b您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。$ o# B4 [# p- \/ s5 Y
0 C; B( x: _1 O) z
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 ' q- U% n- h. A( n( _
数值分析 发表于 2022-9-25 00:20
2 V4 }5 |. K3 @9 }这个不是这么比的吧。。。0 |& n- x2 J/ s6 Y

  T& m% K/ j. j0 V3 }3 E: {; J您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
( Y/ r& ], `+ R+ K- Q
/ x/ p& X$ f' `8 e
有道理。
$ N# |) W  m7 E$ A5 B% k所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。- G, D+ u0 n9 Z6 i/ u: M9 y# C$ R

7 `% l5 a) P' g! p3 G* T我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46  a. X( O0 b6 _9 X- v( u9 k
有道理。$ |1 B8 U" X9 |' t( E( T
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
9 Z/ F2 E! r/ X( x6 m( z  ~
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
1 e4 }/ s5 m( C, tWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20* M6 Z# t! K' ^. x
这个不是这么比的吧。。。
/ _4 M% u) G: k* `6 k; l7 Z& U# p5 z8 ]. W2 r" ~6 _# s
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
9 O& J$ E+ l- k! \* v

3 `) Q0 N+ l4 m  C$ I现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑   O5 _( D. R  s) {) v: n4 t
沉宝 发表于 2022-9-25 01:48
7 K. L' i: C/ \0 Y( j8 b现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
, ~- ?& k" D/ \% w! T% S

6 |9 ~0 w/ R; s. k0 s+ y是的,兄台说的对。4 g5 m2 V! f( W3 Q3 B2 Z8 i
& P- I* ]: I: y$ \+ D1 ?
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
) q5 K  w$ y# P) d& }7 G
8 }- B8 V$ n; T' \2 O雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
7 l7 ?+ _+ \* v+ ^6 d0 t) @/ d5 x5 s9 X5 l
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。- Q8 z1 p8 P2 v) i

9 X  ^1 P7 _# E- _" H% C+ M0 r( O6 z0 `当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
+ o4 T6 {) T) U; `' ]& A0 C
沉宝 发表于 2022-9-25 01:27
& f3 E& f* E* Z% K" N' z你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
# ~9 R5 x6 w. z8 w* ?) [

2 n7 {5 q7 X9 \7 f' K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。! h4 e' {/ J3 h2 t! {

( f4 U7 }2 g, f1 Q9 d, A我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
6 f( m2 l9 N4 B; \' S6 I又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 }+ F6 r2 A2 T* z+ \# K# ?& P! M
时间差一倍的结果可以接受。$ @% d, G7 g: C0 k+ K

% c4 a1 S& y& g( Q( M$ a你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 2 _; q* t! S; u% O+ i) R
雷达 发表于 2022-9-25 04:47& j2 R* I: [7 ]  i' p1 p
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
& r8 e3 M3 R# ?! W: Q- L( s

8 h+ x1 \2 N9 t& }0 S* j& n
. y" T7 S1 E5 a' Y% a4 p- i- t0 J
6 {3 Y) n' Z4 w7 b, E能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
/ |, W2 Y  ?4 b9 D
数值分析 发表于 2022-9-25 14:58
) f3 S' U- o  }8 w$ `能不能把这个也贴上来,看看和上一个有什么不同?
. ^4 F% R; P! {1 H
理了理思路,重新做了一个测试。
  y4 z6 n5 u, G  x4 _做了两个 vector 和 两个 float *, 都长 1000009 W( ]4 G4 W/ o& f6 E$ Y; e
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! X6 K" H' T# H  ?  I' M, y" x9 c8 C  Z" P2 e
内循环试了4种方法,7 n3 }: f3 e- e: ]7 i4 d: O; j
1. 直接调用 vector inner_product 247s 2 I; E3 E( L. V4 A9 x8 j/ X/ l
2. vector 循环点乘累加 237s
% x5 v/ B8 G/ I" h/ r2 I7 \/ V3. float * 循环点乘累加 204s9 ]/ Q' I. W1 ?2 M. G, I
4. 空循环 100000 次 202s4 {  r2 Q0 N0 Y! ]9 ^3 Y

' j7 ~3 ~% V. l5 @6 h9 ]不做内循环 200s* }: i: x6 C/ ]8 a* W! q) C, t( j
3 R6 e) i6 }1 {2 g/ m1 t. F9 [
你昨天说的对,内循环本身占比是很小的,大头在其他处理。, Z0 E% d8 N' \+ b9 k8 S) X- V
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
, L# z, V  W0 A/ n' J/ e( p
; `) O2 k' W) r( ~/ E/ l8 m" z至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试). f7 A6 Q. z( l5 N7 }/ n

% y% V% Z* H; b% R: ~(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL): m! g  E2 G6 N' ?  @+ o- U& o  {9 T
$ k; Q( L& @% s% s# K, B5 @9 t4 z
        std::vector < float > vec1(N);
0 X: V9 _) s+ d- L" E        std::vector < float > vec2(N);
* W: b0 u" s4 N4 q        float* b1 = new float[N];* X" u, i' {) R  o. n" Z" v, O$ s
        float* b2 = new float[N];" m) u7 I" l0 d2 z8 u& K

4 }5 @2 G6 z( l/ p' J        for (int j = 0; j < 6000; j++)
9 J  P2 r5 U# \; Y: b        {
1 o4 f3 W" T: ?: g                std::generate(vec1.begin(), vec1.end(), []() {
  T5 y  g7 h) T8 }2 Y8 ~                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;' G( }2 ^$ ^! j9 G0 I# F
                        });) o: n* P6 F& E
* X, d+ R- R- D
                std::generate(vec2.begin(), vec2.end(), []() {
6 J( o" N7 Z3 o                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;& X1 G4 Q4 K% {+ P( n! L6 X
                        });
+ p( z5 X6 t7 }0 S8 w' r8 v, `
0 v! }9 J6 |; x' ?                for (size_t jj = 0; jj < vec1.size(); jj++)
& M( K6 W8 C( K2 Z. ^/ q2 \5 C2 Y                {# M4 s+ p/ H1 u* |, R% u
                        b1[jj] = vec1[jj];6 T# t7 k# B3 v$ I$ q1 c# v
                }
( O1 Y5 B; [9 H& t) x' V* y* {  d: i" f3 d
                for (size_t jj = 0; jj < vec2.size(); jj++)
* ]  I/ Z# j* |! d& p                {
0 H/ O" ^) M6 s7 I- G" j( E5 @* f                        b2[jj] = vec2[jj];
# R! q, H/ @( f; K7 a0 y' ~8 M                }4 I/ J; M. ~% C' A
  _& s* B5 |0 n$ R+ _
                //Method - 1  N=100000 247s  
% Q) N' J8 f+ g  H: d' W' K                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);% P$ O- c5 V5 t+ n) g
                                9 Z( W5 b$ V; p8 V1 j
                //Method - 2  N=100000  237s
! ]5 r) y* M/ e                /*, o, J6 r$ D, |1 b* o
                for (int jj = 0; jj < N ; jj++)
) p$ E, w+ i* z                {
& i$ }- E6 a: y- [" K" Q7 }                        fresult += vec1[jj] * vec2[jj];# T4 {# W: w* q4 D$ a: s
                }0 _  D& b  h) R" @: Y) W2 V% C
                */2 F" e, R- [  L" I4 Z2 E; d
                                
* u* A5 R* v' d. k4 ?. \/ C+ f                //Method - 3  N=100000 204s
& N0 j8 k3 n5 c                /*
+ r) U3 O" ~% S0 t, e6 k1 J: N                for (int jj = 0; jj < N; jj++)
3 E0 u0 i" C- [. u6 C' m9 a6 m                {& S) U# h. Z* Z" v% u1 X1 @
                        fresult += b1[jj] * b2[jj];
5 Z# t# G, a) f3 w                }# D) k/ O7 r2 k+ |9 O  v8 V' w2 T
                */
1 ]# K! H3 P9 U2 x# r
) N% s9 h1 [1 ^" a" h: v; ]                //Method - 4   202s
& \  _6 U5 T0 P* c9 G. m; I* w- ]                /*8 P, b) w  F/ h3 j) I6 k1 Z
                for (int jj = 0; jj < N; jj++)( W" B  G! o9 d8 B8 S% T: b8 e
                {
2 w5 j2 c6 O3 j5 F! \( U( E  Q/ c1 P, h                          A- d+ @# F$ U0 a4 y
                }0 K: p: l) t: x: ~& b6 M% d
                */
/ F: M! e! H; ^% i; W                //comment out all methods, N=100000  202s               
' I* m" j5 q  h: r; f9 E0 c* H; H! g        }
0 `, N5 G  G) s2 B  h, H! e( w
4 @: ~2 Y' ?- t0 Q# C+ h        delete []b1;
. e# L' H7 w& u- ?. {$ W        delete []b2;
$ j- i9 ?# K3 p) F" S+ ?* J/ w( Y

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?5 O% R+ {/ |4 \# ]7 K

* v! z7 d$ R5 C* z% W0 J你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
' k( W. m" O" M$ G
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
3 z' k" J5 W& ]: S. j: Q瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?, s: Y. I# A2 Z  `/ m" i
/ h+ s: ]0 q& a, r' _+ ]$ ^) w
你第二个试验里面的j在循环里面又重新定义 ...

( }0 v& E* U7 [/ n内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
$ Q$ i  u# ]6 s8 K: a+ ?2 L2 W! |$ U9 t: d6 l4 E
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16; g3 T$ V& r" [( e6 G& y
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL: I) C% a' i4 m! P+ L. w

' i( H! u( b0 K: n$ N5 Y! W/ A& d9 e# Y不和它 ...

: w" I- F; M) n- z  [0 v3 |3 A" ?7 J% _( @9 J8 P% t, j& x9 r
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。: f& b4 D2 u* H" T$ @, }, _
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:549 u9 D: N3 \/ Y; W) y
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
5 ^" R4 S/ [) A* v{
' L  {$ e4 C+ T, C9 Y9 s  j        comp temp, xtimesy;

& s' \% {4 X7 F7 d/ e# z1 ]6 j. g. I5 x这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。. q3 P1 w2 T( l- ?$ e# L0 m' K
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?! i& i$ S/ H* H9 l" j  ?5 D& H
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
9 [% O% u2 M6 w' h' M1 g理了理思路,重新做了一个测试。
% e. L2 ^6 j$ Q做了两个 vector 和 两个 float *, 都长 100000
7 n% ~; J) V) W* a8 X3 A3 `2 _8 O外循环 6000,里面先做随 ...
# ^* }& W9 N% T" Q! J$ [4 J1 ?
这个时间是从哪里开始算的?
5 f) J  {' G7 Y我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。. _7 U0 _2 ?0 g: q
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39. m; V% Q+ O/ o! T( {# O% w
这个时间是从哪里开始算的?
5 L9 L3 _, o+ [5 S我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

6 N; w$ A3 N# d0 D( e我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
* O+ s1 u7 s. Q/ p你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
  d8 K: g) y: Z0 Z5 H0 w. P与此对应用数组(指针)花了2S! O7 h, ]* k/ ]' I
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
1 n* Q% Z# l' [" Vvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; [0 V# Y6 e: Z4 T( K/ P+ A{
; ~% o, y$ d# `* f2 C" K9 B        comp temp, xtimesy;

1 U1 b+ v4 j, x$ x# p; {我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗9 [- |, y0 q1 |1 x3 E7 u% g, O, z8 b+ X
9 l& t4 [8 E" N: K2 T; r

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29) Z- r& r: h) t7 y& x! Q
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
5 @' M6 S- v4 [" y+ _" M- R7 r$ t) P! V3 M3 V
...
2 s( V$ q: X& A* O0 d
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
% ~0 Z. T) _' ^4 }: H/ u" X, u. I0 z' I5 e! w; U* ], U) ?
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
* k" [6 _7 p9 c) n: C1 V+ a1 a0 ]# K/ T; o4 o; d( x) U
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。/ z0 c4 ]* T4 s6 q
有空时我会试试 SIMD和并行,看看能提高多少。
5 k0 h- o5 R9 U" n# c( g" w过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ! O. E2 h/ Y. t1 t( S, c
谢谢大家的讨论,I learded a lot.  红包已发  
1 F- ^: e6 p5 U
) }" S+ V* N* g  _. j4 |( W# j) n

  p- T1 p  Q$ L2 w# Q: N& F" M* `





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