爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?: J) C5 G9 P* I
7 ]: N1 D, D" N: O$ Z0 P9 @
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。4 {3 v# w* M. G5 v2 m

5 C1 r6 L4 Y* M0 s. J( N" ^速度优化问题真的很有意思啊。
- B. T. G0 ]2 F. L/ v: K7 ?1 s3 J/ R5 r1 j+ _
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
) }3 Y5 g. \8 L1 d; c6 z! m5 A把代码贴上来看看?
  B9 ?" a. B6 K: G- u  G
' O- C+ y2 M" s& b9 ?难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
4 \+ {' `' f6 {3 o! _
数值分析 发表于 2022-9-24 23:045 {4 O  }: Z, q1 s: ?( M% {3 L
拉下来?拉多少?
7 g, s( [8 o+ ^+ e, K" j把代码贴上来看看?

2 e( z5 M( f& ^  ?' r; c: ]
, W4 B: u" U4 q& Gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
6 O9 O# o7 e$ l- F{
- `+ I+ J7 |: m3 i: Z        comp temp, xtimesy;
9 Q0 k# p; m9 ~+ b3 S        xtimesy.re = 0;
$ T5 S8 M$ M; }2 C/ S        xtimesy.im = 0;
/ J$ X  R/ w: {/ H% ?6 e9 v& q        int j0 = lenB - 1;
- i1 U8 b' M9 d9 [9 l+ Z* }5 ^* Q        int    i, j, i1, reali;) h% F0 M. |1 h5 h0 y0 B
        if (lenA % 2 == 1)
# x, w) [; m8 b* x2 g6 F                reali = lenA + 1;' q* f) ~, l9 `* L4 e
        else
" O8 D: O$ l3 a3 I% u+ z* s                reali = lenA;
) C+ r; U% v8 I9 i. e        reali /= 2;
! p+ ^  W  A* Y: m- }: z  A% S( i2 W+ ^/ K& Y" H. H' k: f
        int nconv = reali + lenB;% x3 d9 X' o4 x( n& o+ H
        //#pragma omp parallel for# I$ A5 G5 Y1 {# K- D0 m
        for (i = reali; i < nconv; i++)+ V" V+ s" i0 k  b# w5 y
        {! N: c% b3 m5 g: M; w8 q
                temp.re = 0;
. U, I3 [9 w2 u' O/ x                temp.im = 0;* r7 I: S2 c% ?# \/ n- M6 o
                i1 = i;! f5 G$ o: H) t+ B
                for (j = j0; j >= 0; j--)
1 |9 H  ~- i# D; v/ {                {
8 L$ y; M% s& ]/ D$ k                        /* floating date operation */) Z# \% }( E% a3 @: T, @1 U! X
                }

8 c/ j- Q. _! ~& C* X" ]        }
9 j) ~" Y3 ?: F}9 u8 w6 K& D: b% e* w) d  E
* ^/ k, c. Q: I- `0 N
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样" Y7 y* _7 X( y

5 C- y; g5 D7 m2 f0 b& L/ K红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
7 R2 P' X( F8 `# B% D. D% }现在call xcorr 100次,耗时78s.' W" Y) T; j+ y# d8 ^+ O
  M8 i4 C8 y9 Q2 e
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. $ s5 k" C$ C, Z5 H1 A7 b

% A4 L' \- t6 [! ~# ?% R; r
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
2 N3 K5 O9 T4 ^Maybe Debug mode?

" r9 k' `/ s. @0 B- o  ?" z
% D5 u3 `6 z! N" r& O. o! R不应该,看我上面的回复。4 t6 A6 }* M4 H. |1 ?3 Q. S0 f! H3 B

2 I1 \3 r' }+ Q! ^* J我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
, Q; k6 |+ l  o1 g- n/ O/ a
雷达 发表于 2022-9-24 23:54
8 o4 d  A* R- _  f7 h- i0 \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' ~8 S; S; h# o" a7 j' N  M8 }{
, G9 a. L! t. t9 d: k$ _        comp temp, xtimesy;
$ z* |1 H3 }& x; ^+ @9 {$ {
$ o+ K# y5 t; X7 c3 j
这个不是这么比的吧。。。6 a9 Y4 F$ V, ~9 T+ Y: e3 |
5 g# X2 n! h7 I3 b5 z7 ~$ G
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' S- t7 J& j9 ~* F' F/ N: Q2 W; ^0 u/ {
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 * G  p# s8 S9 T' `9 J+ l9 r& c! f9 a0 q
数值分析 发表于 2022-9-25 00:20( V8 N1 h/ D2 ]
这个不是这么比的吧。。。
. g+ ~: t8 `9 M& h2 E, ^+ |1 j- p1 Z) ]2 E8 J) Y$ j
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
& m& y0 Y, v- V# c1 m2 l* D2 u( x

$ d5 C3 p! j8 V6 \' {有道理。0 e3 O3 r5 f$ J: R  K
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
  z. g8 f" @5 N- s- c3 h6 u+ P# s* Y0 h( A' C
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
& a1 l9 ^; {* G7 y% V7 R* b& e. \" a有道理。
8 w. ^! q2 ]6 P( V所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
$ s6 Z8 @+ M1 F' e% Z
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
9 P9 X& j+ ~7 p5 @' L$ `Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
: H6 \( Y1 O$ g. f5 q- t4 t0 a这个不是这么比的吧。。。+ k6 M( T; |0 L3 k5 J; i/ [

2 @- H" {. }2 N6 F9 s1 h$ D8 n0 w您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
' f- ]9 Q5 m9 {% B) V8 s& z
! I2 y2 n( S  Z1 Y, B: H8 ^+ p
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
% s) k) L& h# R1 f+ u
沉宝 发表于 2022-9-25 01:48: k; a1 j0 t8 k( n! P/ N
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
6 c4 s8 d: v, T. s; h& p* n  M
4 U" j* J# ~- d7 R! t0 j8 Y
是的,兄台说的对。
3 ]) m) d; R8 F+ Z+ l3 H" J" b! g* g" i
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。) h" C; |0 C1 F$ l! o5 `. y
. C3 W$ Y1 p" w% e, W3 R
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。0 o8 G- f& J2 U2 V! Z5 M
3 s  d7 g+ U# o% ^( E0 v
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
- h9 n# S  B( O& i
" I6 @( P4 ]1 u, ^当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 7 Y- G, B0 F9 ?% N( x
沉宝 发表于 2022-9-25 01:27" R/ O' A) h( M% r
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
: s4 }) S$ X2 |

. r8 [4 X' s4 x: x7 u! K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
* E4 P3 g% {6 f; \6 Y8 G1 o2 Q$ d% N* m+ [) }( G
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:478 e. y1 Q9 e0 K3 G5 g- t
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

  p* |9 n8 x* w; x  j4 }时间差一倍的结果可以接受。
9 y6 M- z9 N: |% L
& u, L( _7 `! R- W  m5 N; f你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑   _: ^# E) `2 N4 B3 e0 E6 M
雷达 发表于 2022-9-25 04:47
7 O& @/ s% A7 |' `! K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

; Q: G4 X" A1 r1 S* Q4 S  H1 ]# T# l+ F3 V; I) r

. R: u0 K* r0 W: O
% Q' `3 H/ l+ X( r2 D能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
2 A/ c$ c( v- Q- u9 Z
数值分析 发表于 2022-9-25 14:584 N7 X2 @" E- u- a. W  }' v2 k
能不能把这个也贴上来,看看和上一个有什么不同?
- \/ k! w' X5 Z
理了理思路,重新做了一个测试。0 I( U* i% U1 T; s) e4 f; _6 w
做了两个 vector 和 两个 float *, 都长 100000
- R* s$ t/ P5 j6 L- M2 A& k外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
# S, `$ [8 F  D  U, ?- k; X6 s9 ?6 q) c" A7 K# H7 p
内循环试了4种方法,6 G1 z  C, x6 P; S  J
1. 直接调用 vector inner_product 247s ; K6 k7 U  T6 P9 B
2. vector 循环点乘累加 237s, `4 t& ^, T8 Q! k; ]- [
3. float * 循环点乘累加 204s4 s6 r3 {: [* [4 ]( {1 I4 U7 t9 c
4. 空循环 100000 次 202s
9 I) N  W& c7 a  t" {, a7 b& ^% [; G, N+ o' c
不做内循环 200s
3 @% _1 r; W" o8 ~2 n% L7 D
# u# A, \# n& j6 d% _/ [' S2 \; W你昨天说的对,内循环本身占比是很小的,大头在其他处理。6 t! Z" t; r/ E& M+ J; }
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
: R; R) ^/ Y1 r
* s( c- _5 T5 W' X, }1 Q0 B2 L至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
  s0 P  Z$ I7 G! ]+ e& X
% Y4 e$ @  X% I1 t" x(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL), y1 z3 |3 P5 U' S! E

  L. l" |1 W( j
        std::vector < float > vec1(N);
$ b0 O$ E3 S! y/ I& d5 M1 H9 A4 @6 I  a: ]        std::vector < float > vec2(N);
* t; d" A4 s: N* j3 q        float* b1 = new float[N];
# X1 Y) g- u! ]% N2 U: Y9 t        float* b2 = new float[N];" y4 y2 p, v& |) s+ L6 j
6 m4 F5 V- p# O" c& ^$ Q8 \
        for (int j = 0; j < 6000; j++); ~+ q0 X/ J3 t0 B5 V. @
        {1 K7 n) N' T% ^. K7 B7 b
                std::generate(vec1.begin(), vec1.end(), []() {$ U$ I- r  L3 ]0 z' X4 |4 m* l
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;( A" C6 e9 o* V
                        });
7 ]+ o* n5 M* F9 F2 a) T$ q0 J& R8 S) j6 a% e/ j0 m# h& _* p
                std::generate(vec2.begin(), vec2.end(), []() {
& r- j& a% K0 _                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;5 G  j# z& ]6 m; h7 n2 u5 s
                        });
1 ~+ ^4 W& o# u* i
+ `. Q8 b, _, |$ N+ L                for (size_t jj = 0; jj < vec1.size(); jj++)+ {; b" }, _# j  o5 a2 |: R' f/ j
                {
6 Y4 S' V  N; [4 L/ j) \                        b1[jj] = vec1[jj];
/ J5 q7 h. ^% W+ I                }* p* D0 X# k: r: c) _! h/ C
8 c& d7 _) U) C5 c
                for (size_t jj = 0; jj < vec2.size(); jj++)* T9 W7 e$ h7 r+ H& f
                {) B/ m2 U; P# A. i' U
                        b2[jj] = vec2[jj];$ K3 n  y8 t+ \( A3 p% K% @
                }- Q3 D1 }8 h, I4 ^4 W% M% [

- Q* v% V# Q0 G4 h2 z                //Method - 1  N=100000 247s  1 Q; S3 b0 ?0 n, C* S
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
0 H8 e5 H, G: f: J                                
: _/ `* v6 i' F, K9 E                //Method - 2  N=100000  237s4 ]$ w0 j' E. {$ A2 `: R
                /*9 G+ O5 a3 N) D4 Q6 p
                for (int jj = 0; jj < N ; jj++)/ X( s2 a/ S! |" |% C3 Q$ h8 ]) O# i2 I
                {8 r. u% ?( T7 v6 P( |5 q. D
                        fresult += vec1[jj] * vec2[jj];
- C- P  _  S7 r                }$ Q9 r* a  w# e; C& e" w8 G
                */
4 J: \1 J0 E: u) s% G1 n                                9 }5 \  K9 N: O9 s5 X
                //Method - 3  N=100000 204s7 H) [% ]: G. c( {/ {) w
                /*
) y) k$ L* k  a) R, I5 K                for (int jj = 0; jj < N; jj++)1 k/ k$ Y  [# Z7 U
                {
9 D; M1 ]; M8 u- y7 S                        fresult += b1[jj] * b2[jj];/ H  n* h2 U5 J& f7 p
                }# w0 I& l: t2 x4 \
                */  k& h( M9 ~6 X/ w+ ~8 t& t

3 p! `# b7 p8 J  V                //Method - 4   202s
) t8 L; b5 x4 T: X# [3 `                /*
- Z+ C  y, |- |/ v                for (int jj = 0; jj < N; jj++)
6 P4 O1 t5 W. |, ~: L" J7 Z" y                {+ m4 j) X0 j' _/ m2 _" a
                        
2 M8 {* S" j+ c+ O  j8 ^                }
0 b" C  V3 o- F                */) r5 o2 a/ R* y/ U. ~4 P
                //comment out all methods, N=100000  202s                9 t* ~. k% o+ o9 ^# s1 l* _
        }
3 d" \, y: O8 [% q8 X  K) K) b( ^: K# t( a
        delete []b1;, `4 }1 B% l# b% q6 D
        delete []b2;
0 S, G; F- R+ T+ Q

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' s9 f( W* ~2 Z: e! c
4 k% Y' x. E4 n" R你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
$ K2 C9 _2 h+ L
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
' w: Y+ m. d' |. N瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' ^, d5 c3 R  \( }; v* [# D3 M4 ^0 c0 ?8 c# p) I3 y
你第二个试验里面的j在循环里面又重新定义 ...
% \5 {( P  ^  u8 U2 z. k# T
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. L% {( J; \  U+ @

" ]* K3 ~2 i! h- W0 q3 r5 O不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16' E! u3 m/ N' b  o+ w
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ L% M6 q+ u: k+ s/ ?7 ~
- Z$ e% k8 Z9 h" \8 T+ c
不和它 ...

1 s. L- d3 x! B, `7 L8 W5 a: a, J5 o
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
  J" M% P" y7 [' D8 T6 `后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
5 a6 ?' x; n9 `; jvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( ?& R' K5 Y- x* l
{( f( M  B+ K% M% H) }, e1 Z) |
        comp temp, xtimesy;
( o$ A! E% l: \. k$ y0 s
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。. a& R* F' y  Y/ \2 @# Z9 V, F
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
# d' u( Q. Y0 x& o" WVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
  b+ G7 V) o3 \" f/ t: A+ @理了理思路,重新做了一个测试。
" {  s0 J5 p' N- s6 L% d2 T! X( i  u做了两个 vector 和 两个 float *, 都长 100000" ^8 }) [) O+ K" T6 L# h) j: m
外循环 6000,里面先做随 ...
2 k5 g4 q* c! G; |* u) C% E: R
这个时间是从哪里开始算的?0 ?: G$ z+ A) i  E
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。5 n/ ?# z/ d( Z: T! L
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
3 @) y# H9 P- s( i- f: i这个时间是从哪里开始算的?
+ J9 ^" F! d! C+ s8 W% u; v" O我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& T" ?& s) r) H# S
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
- G% _$ O% M0 g" @; `你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。3 _; ^8 G$ ]. B& z
与此对应用数组(指针)花了2S) G' f( _8 [( k: O
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
3 F1 d$ C8 b% F% i0 fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ j4 q/ C  a4 y. y$ [{! Z9 c' F" d/ q$ ^
        comp temp, xtimesy;

8 D: ]/ W$ V$ y/ t5 [我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
$ j- ~. {) I4 }. c6 R# k8 y' b+ Z# P: T1 N/ e# L& o* }

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
6 n$ X; ^/ |9 S我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗# T+ K( k; w; i8 T9 M- O( V
6 U! j% j" x9 }: t' |1 e. N
...

- _5 q, N6 ~/ p7 y9 Y你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
. X3 p$ o9 t% C9 ]# a% t/ h3 Y3 R1 c- u
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
5 t( l1 Z1 H5 X' E% O9 B9 {' p( r# x1 e; P
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
2 B6 Y& s! n8 ?& E9 W* M  S有空时我会试试 SIMD和并行,看看能提高多少。; j# y7 |8 M- m& x* w* C) \' N
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
" J9 L: M4 r( S% k8 l! ~% P谢谢大家的讨论,I learded a lot.  红包已发  " @( C! Y/ E- \& u* P1 D

$ O+ C/ r, ?7 p6 l& l& X
  B1 l8 k; W5 Y' z9 x/ m& |, ]3 W$ Z$ O2 F8 L

9 x  }; B" G4 g- ]8 P/ k: v




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