爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
$ L1 Y# k8 `: r  y. x0 I5 ]9 k% P6 C6 ~: |+ M1 \; h! }
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
' k: E8 w6 r( G4 n; H8 }7 K
  V' n5 i6 X; l% A1 P! \( C速度优化问题真的很有意思啊。
2 }. Q) N9 I9 Y' {( D
9 k8 ^' i2 \* }/ d欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?  _: k& U: J% I/ r) S& E# \
把代码贴上来看看?
8 s5 O( s+ I  Q- P7 K* t: {
& H& q1 {* ~# o5 E难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
) q! s; {9 W( m1 U8 T$ g
数值分析 发表于 2022-9-24 23:048 ?. p+ N( W# i' @, m4 U* {
拉下来?拉多少?( }* K( Q# d: Q( j
把代码贴上来看看?
7 u; l9 Q) R( l6 J* O' V
$ O+ }; I% Y. A* z
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
0 B0 i; l9 C9 Q{5 h* t4 l4 A. }) J8 L) Y, O9 l! o
        comp temp, xtimesy;
% j) |; L' B* d' a5 g        xtimesy.re = 0;" u/ J" J; H% K
        xtimesy.im = 0;
* Y% o4 t& y$ i; p% V7 D% e2 A/ Q        int j0 = lenB - 1;' t9 S1 s0 R& d0 N  I
        int    i, j, i1, reali;
# K. x4 {- W8 M+ F8 L4 v        if (lenA % 2 == 1)' N; O2 \1 Y3 ?! L/ ~; w7 E7 F4 E) r
                reali = lenA + 1;! d: @$ ?/ z8 g# [/ z* e& S
        else
6 w6 J/ Y0 k1 Z9 z                reali = lenA;
; C9 k5 T/ X6 ^- `' E9 m) ]        reali /= 2;: s. v) ]+ Q+ T. L3 c

, y1 G1 h; C8 d5 ^. j" ]        int nconv = reali + lenB;
; q0 U! K: \  B9 h" B, e        //#pragma omp parallel for
" l5 h/ u+ O, g. E* g        for (i = reali; i < nconv; i++)
/ U  c  Q- e# K7 a        {; ^' @1 T& f, S( X+ a* K
                temp.re = 0;/ N& D% _) e6 S! q" o! n9 z$ T1 Y: E
                temp.im = 0;
' x2 N( Y: x0 |9 C, S# V4 B; e                i1 = i;0 i) |# o9 n# w' _
                for (j = j0; j >= 0; j--)
/ l: |$ a$ l" V3 b$ k                {0 ^0 `) a- p$ L9 c0 M5 Y
                        /* floating date operation */
: \: t, `! ~# d" o                }

$ S- d  O# I% U% n2 }- e        }
1 b- j& B: m/ D: d7 p5 T}( m2 K. X" x$ z4 c
; q) G2 p) O! b- a
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样+ N% c# |) ]3 J$ g9 O6 L$ J9 i* |
7 o3 A0 Z0 D* t/ M! _
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
- h% A1 i' q- u2 Z现在call xcorr 100次,耗时78s.! ^8 ?/ T# l! O% y0 u6 ~
* v! M6 X( z! x+ P
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
5 E4 L: v/ @" L0 J5 n) _5 z" {% J  }4 B( Q

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33' b5 e. L6 d. |2 C! r
Maybe Debug mode?

. t* V% Q8 |# P9 z8 P6 Z' U+ P* L4 W  z, U$ g3 A* a
不应该,看我上面的回复。
* {' R  D. R; e) c, b, I5 q
6 A! {0 f* S" o5 f" B) N0 H我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
+ i+ `) H0 H: B  h2 E4 U
雷达 发表于 2022-9-24 23:54
% u/ |, Y7 m6 y* j/ H4 H, |# S$ ?6 rvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
6 g# j* j9 O1 P6 y{
! }; N; S( V) p7 m        comp temp, xtimesy;

7 ]- e8 t/ N9 ?! D
& P7 D$ ?; M- S1 G# B( x4 h1 A这个不是这么比的吧。。。" r; w; S) X9 E" ^

" Q- \* {) Z7 E, j$ [0 v% ?8 G您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
& v2 Q7 j5 p) X* p" ^" n$ v; j5 J6 y, |8 `% ~
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
8 Q2 Y# N9 C+ R) r1 }  Y; \6 ~
数值分析 发表于 2022-9-25 00:20: }% w& |1 ^; l) K3 C& g0 |
这个不是这么比的吧。。。; _$ A& f" d2 E
% x/ P9 v" ]- W; m) J. m( C
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

8 v8 M, m8 x+ q+ G- I& w3 d/ o: }  ~& P
, ~6 Y, R- z8 k$ |: l有道理。
6 ~2 `3 `( b# r' H% }0 f7 ^所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。6 r& c" T4 r0 U6 h( q. a  }

8 t4 _# x0 W1 a% R0 X7 _9 Q- ^我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:463 O0 _0 T2 o  l4 ^0 g8 ?
有道理。
, _' Q, _. ?/ x; c* g  s" s5 x6 Y所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
! l, z1 z6 {: Y& R  d6 M1 L
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多1 P" L: @. N" r9 T: z
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
. ]4 J9 I- U' g3 F) g/ m, ?, L这个不是这么比的吧。。。: Y  z6 ]/ c8 A8 o: g& T4 ~

# p* w- R) P5 A您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
# _% @3 F' b2 k7 t+ |0 l% w8 k& ?6 z- h

* f% m9 z( z) D9 s现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 9 J# |! }. r# C6 g1 [
沉宝 发表于 2022-9-25 01:48! V4 h7 p- E# l' S8 j
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

% `1 A, R; |& M; r  N  s$ V3 a$ A5 I  Z) r
是的,兄台说的对。
/ b: V& K* ~$ R6 o4 \/ t
7 R& C1 J& z$ V. r其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。( b$ ]" d7 K4 o( o6 L# |, r. V$ i4 U
( B5 M: ?' S/ ]3 U" @
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。5 i% u4 x! w( x; ~  x. t1 Y; j
# r5 ^& B4 A2 ?5 x
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。# O2 j4 m; @" y5 l" @
0 m5 O; N$ S: m
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
, \  K; l% A5 Q  ~! r- |8 U
沉宝 发表于 2022-9-25 01:27
0 @/ E* `9 I( Z8 g# u) U% M你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

" t/ W. Y* ?2 R, b
6 e- M+ L1 H/ T$ ~- x7 @' w" z又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
1 K  K' Q$ Q! A5 Y# X3 ^" _: }
& P% x" g) {4 t; d9 q( Y我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
; H: V. u  s; a+ b1 H  ?又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
: }8 T8 F4 W- z- y! K  a& K
时间差一倍的结果可以接受。# E# z# {/ b3 F7 w- z8 i; n% A, p
$ R$ K; P; \7 D& m1 V" I
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
( h% W/ ~9 E- D4 U  l1 j5 B4 f; u
雷达 发表于 2022-9-25 04:47
( ~6 }# L6 L4 d6 Z& D3 S$ n又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

2 l" q1 ~! P! B% R; o
! N+ B* j  W& v% V* o( a& @
7 A, O* X4 u: }: p. \8 c7 R/ k& w# F3 a; r: r5 r4 k$ H' P$ T9 |- p
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 5 O( ^" ^/ j4 v% E1 n4 A3 R
数值分析 发表于 2022-9-25 14:58
- ~6 i1 N- M( G能不能把这个也贴上来,看看和上一个有什么不同?
7 Y% ?( r  M3 s
理了理思路,重新做了一个测试。
4 q: I! C" K* W9 I做了两个 vector 和 两个 float *, 都长 100000
2 K- \4 q" q$ g1 K+ F4 W1 {外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.! I! j" n: \$ s
- {- x3 @. X4 U, i/ M
内循环试了4种方法,3 W9 C) ~- }9 `# Y
1. 直接调用 vector inner_product 247s * p) c2 }" t2 U6 |3 G
2. vector 循环点乘累加 237s2 ~% l# M5 P4 _
3. float * 循环点乘累加 204s
0 Y6 G0 {2 S+ f: w) e! ]  a4. 空循环 100000 次 202s! ^- E+ s" `+ e! w2 l& e

- {! ]; I7 l2 f- {6 Q不做内循环 200s' U( e2 I9 z' W  Y" x( v
/ \( @$ |9 X1 `: `" ~' F0 f
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
) m5 C, U# J. {) c2 }. _" ]另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
  e7 s9 Y: U, [8 ~  ]3 t; Y8 N. T: l* C  ]+ P
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
7 E2 y( @/ [' p" N  P+ n) o2 i5 S
0 }. q! |7 Q6 M5 f3 r(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
% {. I- L: J5 B! A: }
1 }0 f) E+ I5 N) D: c" r/ A4 Y
        std::vector < float > vec1(N);
) z9 A! C' d2 f* g3 U        std::vector < float > vec2(N);5 P7 K# t9 ?3 i. g9 ?; ~+ g
        float* b1 = new float[N];) I1 ^1 r. Y8 p0 H3 e
        float* b2 = new float[N];
5 h; @) s  C# V- G1 a
+ K8 \$ h& a. u- S/ S$ p" @* j        for (int j = 0; j < 6000; j++)* d. f, A. z1 }( _
        {2 r2 w2 K; ]: t) v
                std::generate(vec1.begin(), vec1.end(), []() {
! \& k/ O2 C! C0 B/ H                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
5 X& [% K/ d- n$ \- c  r                        });
5 P6 j5 U0 w3 u  a. w8 P$ g. D
' X  s2 v6 q3 |# V$ I) j                std::generate(vec2.begin(), vec2.end(), []() {( {5 A% Z. ~: \/ g
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;8 N8 ^4 D: N2 \1 R4 h# h  ]
                        });. p/ Y5 j' a  G+ z
1 b0 F9 s6 H7 \- k: o: I& W- C% x
                for (size_t jj = 0; jj < vec1.size(); jj++)
& x! b; B! k9 S8 c  R: f                {
2 `# i7 V" f# `% A; p3 B6 V                        b1[jj] = vec1[jj];; A/ F# U( g3 [; ^  E# a% O! B
                }" P" A  B% X& M0 p8 A9 h
4 i8 b, ~0 t( W" ~& y. W+ G
                for (size_t jj = 0; jj < vec2.size(); jj++)- g; a1 A) P6 i+ D, e# A
                {
5 t1 x) x) T, A" [. B                        b2[jj] = vec2[jj];" d! r6 I3 d8 r+ O
                }$ L0 [1 z% c% ?- B9 G0 r
6 F. s; ~) `6 j7 a" r
                //Method - 1  N=100000 247s  . O% N& U2 `, |1 V2 _. H
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);. m' }( V* p" f$ r. E; u
                                1 g+ R2 Q0 J; {5 ~5 t
                //Method - 2  N=100000  237s
' `: s5 r8 H9 C0 J( b9 p                /*
3 k) G. ^* \3 R* N7 `3 K                for (int jj = 0; jj < N ; jj++)
6 ]! V/ i6 V3 ?6 b                {
# `! U" a/ f, [/ s0 X' i                        fresult += vec1[jj] * vec2[jj];3 ]6 ~, w5 L' ?% [! i3 _! T
                }
* @& t% |0 R7 y4 J6 ~                */
3 r3 s% S, P: W* J0 ]- v- h                                
& {5 b* Y/ g* t: |& `! }3 w                //Method - 3  N=100000 204s
3 y0 ]' j0 D, o! n* Q                /*& R& D$ K  f" \* r9 i
                for (int jj = 0; jj < N; jj++)# u+ }; X2 {. e1 l: _- e& q2 _
                {
( r4 ]* v* V$ d                        fresult += b1[jj] * b2[jj];9 J* k6 r- R" d; s
                }+ O/ a0 }7 H; \+ z
                */5 i" j2 V, l/ f7 D% ~' [9 c9 l5 q
& _9 u, K% a  G: r' `
                //Method - 4   202s# r& u! }1 \' d. i' Y) K
                /*
0 x) i3 Q# e6 t0 b* d8 o                for (int jj = 0; jj < N; jj++)
( w% Z% V/ v" S) j                {
5 g& R4 `5 e' u                        
' w# r' n( R6 q, a. l                }# w7 w$ b( G4 B4 s: ^
                */4 H0 ]3 F! ]9 y5 B# ^
                //comment out all methods, N=100000  202s               
  m* r' \. W, G$ s1 h0 v2 V+ P# ^        }
) J! R6 L9 y# i: C: k
* q& S% k/ y% o) L% [6 M4 H. ]- t5 G        delete []b1;0 Q1 @6 O7 k$ R9 \' t* B
        delete []b2;
0 ~8 [( \9 Y& \4 a$ X

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?6 \7 w" w! j8 h: Y& w2 h4 z  d, e. ?
# a4 C3 ?* a$ o" `* s; x
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?, {8 G( @& W. [0 k' a' y

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15" Q1 T; l" |- @! E6 G3 H3 Y
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?4 {; t' t5 w3 h# q

# e, \& X4 B/ Z# n你第二个试验里面的j在循环里面又重新定义 ...

, ^, o, e0 h/ G内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL8 A7 ?( W" j# [. V. ?

# ~& f" v, |9 l) s1 }2 }不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16  L& G5 |2 ?" D1 e( \3 w/ y
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL5 d+ E, Y1 U5 ~+ I( P1 k. e
" ]1 G+ J' H7 {. N
不和它 ...
# t1 {; N" l% X  P) m' t

0 G2 W* v) H- S+ j4 E3 K; B不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
: M! _3 c, i$ P5 D3 ?6 P; ^2 `后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
1 R0 s) D9 C* r) K8 y/ `( S$ fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
, ~' Y; V; S' R, q/ n( z3 Q{
: A# V9 u3 [! s6 z/ B% f        comp temp, xtimesy;

. [8 ^1 s0 q) O9 ?" g* S% {这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
9 ^+ p9 {% ^2 e. r! R1 v; B1 I内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
: h3 |% `7 a$ H' {4 e# aVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
/ S+ ]2 f' V4 |( k* m4 ~理了理思路,重新做了一个测试。$ |4 T+ M' g9 g. y( r
做了两个 vector 和 两个 float *, 都长 100000
+ P# p! G7 |6 ~. ?4 `7 U; z外循环 6000,里面先做随 ...
% v/ J2 o# W+ T$ J; h
这个时间是从哪里开始算的?3 }4 e3 I6 P2 R4 r
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。/ |' F* r6 S! }3 {% ?$ Z
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
2 L% k1 g2 N* N( P( `  o这个时间是从哪里开始算的?3 v# }6 ?0 q# U5 u6 Y
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

6 g* ]$ Z5 H' y' n9 ]: ]我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。0 F- P" Y1 r6 m  s5 Z' ?
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。9 J( P1 T$ a3 _2 t
与此对应用数组(指针)花了2S
' \4 C1 q+ v8 O! k+ \你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
8 R0 ~; ^2 g. U- z2 Q+ U0 Uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ V9 p6 P, v9 W4 V{+ Y6 T" h) U' I/ _+ b( S
        comp temp, xtimesy;

. d& B1 _" T4 P; y6 u8 z% v我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗* ~  ?% M0 C9 G5 m4 Y1 w3 J/ |
# u0 y" C: J* N1 H1 n0 A# Y

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:297 R- Z" J+ c/ ]) b2 D$ T
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
- t) v# F8 I% U6 P. S4 \; w( ~0 Y8 K
...

6 X" @. ?$ d. P( Q2 a" |你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
& ]! h' V4 P  e# _5 B
5 g5 Y# Y; t' h* J# V+ j9 w( S" R雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
5 q! Z# M9 J- i) w& n. ~. Q5 G8 g9 v4 g2 I# [5 n' \& d, ]7 X6 `
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
! M6 l1 V9 X( ?9 \% T  J/ C有空时我会试试 SIMD和并行,看看能提高多少。
8 M+ n/ Y" Z; P) N过去7、8 年没有正经用C++ 写过东西,没有 sense 了
* R! }2 @7 j0 @, \8 }谢谢大家的讨论,I learded a lot.  红包已发  1 Y: z: @9 y/ @8 O) }

% k3 D$ v2 U5 O/ T' k. T" U
" D! i- `3 m5 r) a. T9 s$ ~- P6 x& s! [) \# G) p0 m
- R' x. |. }- B- f7 y





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