爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
/ B- t4 v2 q% y6 c6 Q
- D7 o/ a% d4 P. D$ O自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
1 X" u) F) _7 j6 c) }- ~  J: s( g; R% ~" ?1 m
速度优化问题真的很有意思啊。
! l2 k4 g; b* j5 ^. h3 {5 j9 G2 p. E1 B$ U
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
1 M& A# m) q) e( H8 |. s把代码贴上来看看?
/ a- N3 B8 w$ v3 Z6 u) T5 m3 h. h7 w
$ Z/ A! B0 R/ G: C难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 + Q/ k! s& q9 G' u% c- X
数值分析 发表于 2022-9-24 23:04
. y3 j" x/ @8 O- u* L% ~拉下来?拉多少?% a! L' h9 X( \
把代码贴上来看看?

) o! D; O) L8 p8 K, m' T' s* ^) c, p3 H4 ~4 b2 m+ a3 o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( {7 }5 z. N$ C& v6 J- n
{
7 W/ r+ g: D$ o0 h! [; ]        comp temp, xtimesy;9 t3 l9 q5 t: l8 G$ c+ @
        xtimesy.re = 0;
$ [# |% z& f( h5 K* H4 X        xtimesy.im = 0;8 i* c) q) _$ Q$ \
        int j0 = lenB - 1;/ c; {2 [) ]) J( \( U' V. \
        int    i, j, i1, reali;, B& ^3 S; Y! g& \5 a; l
        if (lenA % 2 == 1), M1 N% E5 K: t* Y( v) Z5 t3 l
                reali = lenA + 1;* E3 a# x+ X$ Y* O
        else5 V6 K9 s$ d$ P: u- v* `
                reali = lenA;
( L* L! D% J* Y7 ]- `        reali /= 2;
) P9 x9 \% a4 F* Q' D. W/ L/ h; n: ]2 T8 m
        int nconv = reali + lenB;) y3 Y/ }1 l% s  R( ]" ^+ Z2 X
        //#pragma omp parallel for: t2 s9 a4 R, h& d0 ?9 T6 V
        for (i = reali; i < nconv; i++)
! j8 |5 t  P; K0 k( q1 L& E+ m& `        {
; D. i8 S) }  z% A- e% T5 R" \* e                temp.re = 0;. L6 y, O  w/ U. \( z6 g( I
                temp.im = 0;8 \* g8 ?4 I8 z6 Q8 _$ ]( a5 o; }- d
                i1 = i;
( I  ]- K9 u; p5 q  [                for (j = j0; j >= 0; j--)
0 W+ R" f! ~8 B, A                {% `6 ^' f3 q% C7 Q4 E
                        /* floating date operation */" U  Y+ b& n+ C# b3 V9 ^- @8 r
                }

( R( g1 R% c8 U6 a( u0 j7 L        }
: R% A0 r4 J2 |$ N}
7 ]7 \$ ~. W/ K: o: ]. D# H$ S1 o! _: R" e6 R" L1 z* x
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
6 l9 i* r  G* C* z+ V
3 i) H/ K& ?: o( T- j2 V红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。0 k0 x/ A# r( g! {4 s& i
现在call xcorr 100次,耗时78s.
% g" ?9 v+ ^) R* ~9 @  B2 W
$ U- i% u1 D& V如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. " j8 E& A# G, r' E. o' `

2 n* k% ]5 ^  p
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33: _" w6 X, B- S. t
Maybe Debug mode?

1 I4 Z* E+ \+ k# W$ L1 c+ y
/ ]" y+ T9 w- i% r; j% e+ X不应该,看我上面的回复。5 |0 j- p2 U7 c/ }. l& l

2 W) L) I( T( y* g我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑   X+ L- `  p+ e6 Z: m/ @; o
雷达 发表于 2022-9-24 23:541 \. q% Z" u* L# Y4 B4 F
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' P7 e4 n% x; i% I" Y{
  e0 W4 S2 a9 M. |1 a& Q        comp temp, xtimesy;

& {$ P; v# D" l# K* p5 g; A
: D. g1 l4 A: y0 W0 O这个不是这么比的吧。。。2 T2 g2 \- s$ `+ {

& e1 y% ]" y# I, Z7 d3 k2 h4 [您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。, K5 Q* N! M* q. o% v7 b" D+ F

' c+ a: Y. Q; d' E7 Q2 D" @) ?而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 - u  O4 M: z% y
数值分析 发表于 2022-9-25 00:204 ~0 {% b  {6 A% v7 L- t$ h" Z% |
这个不是这么比的吧。。。) B+ X. M8 Q. d$ c% T, X9 T
/ i& e+ z( N8 S$ z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

/ {) o  q" v5 j! A. N8 s6 k& w
, Y* X4 [( K8 i) |1 }. c有道理。
! o8 k1 p0 X4 F% r4 i, M" n0 X/ b所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
+ k% y' X  T2 I, d' L- v
; y2 l) T! t9 U2 g/ q3 W我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:462 ^# A( x% _. q! b7 c
有道理。6 F/ A  }0 i- e$ Q; c; a: O
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
, v. B) g- t8 F2 }2 n) ]6 P! |
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多* J, C0 j' C7 c5 C9 e
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20. g7 K: `8 E$ z
这个不是这么比的吧。。。9 X3 N: `- t1 m# v+ G3 |: B( T# n2 O; i

! T1 ^/ r) u5 S' Y; u6 b8 |您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

9 G  h& C2 P0 M8 r3 v) [4 h2 Y
, n8 e4 C$ f! Y; F现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 2 M4 J* `9 s- k7 ^+ x$ W$ v5 O+ \
沉宝 发表于 2022-9-25 01:48
" G0 u' M0 P1 ], {* G0 f9 \现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
. x1 C2 ]; l9 O+ M
8 ^: L$ Y/ s7 Z
是的,兄台说的对。  m- K$ g: G- G% u
4 r' e6 _6 L0 |: h! U. ]
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。3 }$ z# x# ?( h0 {6 i

1 l8 t3 `/ [! ^. c1 K  E3 g+ ]0 O雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
0 y' K9 G/ H; |0 p( P; e" |0 s
3 W6 b2 c# W2 E) u比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。; f; b0 F3 \  N" L4 \

6 ~) ?7 m8 s. H7 G) K9 p6 @当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
! q) L. E* N5 e
沉宝 发表于 2022-9-25 01:27
0 u" Z6 x9 W1 f0 z) M! ?% E你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
. L* c( V- v  ^6 B1 D& P

" ]$ q2 n& X' d又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
5 @: j$ x5 V/ W7 ], |5 O
) e) S9 Q/ W9 _. ]# R, a我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
5 v2 R( q! L4 g0 g, L, o又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

; l: a, k# [! P; `时间差一倍的结果可以接受。
2 A4 ^. d3 ?. P" \& |! ~" \& L
, E( q% Q! v0 Q9 _5 v: y) r你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 0 d! T  }- x2 |: O  J5 h
雷达 发表于 2022-9-25 04:475 v! ]1 F1 L9 K- [8 o) o- Q
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
- v, T* a; k6 `
7 H! z! E- s2 `' B1 o! T
9 J( {: G6 ?# V5 }. F) `
4 g" G4 w, p" F$ g6 U3 ?
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
: O5 r% O1 e( x' n8 ]* m
数值分析 发表于 2022-9-25 14:58% ^. g+ P( X  k; @9 j. [
能不能把这个也贴上来,看看和上一个有什么不同?

1 G9 {, x, D0 k' B  B9 p理了理思路,重新做了一个测试。
6 E9 v) K: p5 H( B做了两个 vector 和 两个 float *, 都长 100000
+ F; J2 Z( D( u& K3 M) R3 T外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.5 o, W; K9 G: Z) r) s- O$ Y

" w, E: s& c( ^' E内循环试了4种方法,( |8 U5 @: p* c# s0 B4 I
1. 直接调用 vector inner_product 247s ' }" Y- ^0 L, d/ K3 ?; Y( h8 c; T
2. vector 循环点乘累加 237s
* e1 b, @% B5 T+ b3. float * 循环点乘累加 204s. S6 D0 ^! D% G5 M, j
4. 空循环 100000 次 202s+ K+ l+ [, |8 a2 R% M

8 y4 J0 |+ Z& ]5 G不做内循环 200s
3 V3 B' W: f/ k' x' ]  M4 C4 E% Y  O1 z7 h
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
. a6 Y  t. F1 z/ Q. a# K) z. R另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
! }8 H+ f; v% f7 f- g2 C8 p( N: v1 U& ~: R
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
7 E/ t' n5 s+ G- [% X2 \$ }$ }7 @/ I9 o
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL); ^3 F! h( c  T) v7 c0 `7 n% b' O
0 }5 [& i4 C- L/ S6 I8 T9 ?
        std::vector < float > vec1(N);& g) K  P$ U- @! {* w3 d
        std::vector < float > vec2(N);
% ^$ b4 d) i2 a" j( ~        float* b1 = new float[N];5 }  ~7 d/ @4 T5 W& G! B# h  a
        float* b2 = new float[N];
# X( b$ N2 ]. @4 A0 Y* R# F
' I# v& j1 t8 ~5 y0 {        for (int j = 0; j < 6000; j++)
: p6 v/ a& z4 U, a3 ?* }7 L9 k        {
7 M. P5 m! _* g) W                std::generate(vec1.begin(), vec1.end(), []() {/ V, C& B! P2 n% r
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
4 B9 K( P+ z2 B% U                        });
8 ~4 n7 P+ u% y. N1 h2 e) n
* A7 H8 o& K( X  C; v8 E+ N                std::generate(vec2.begin(), vec2.end(), []() {: s4 b* A% L3 `
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
6 D: U) x# u0 m. d' `: _4 I7 ^# `                        });/ N8 O5 X5 i  {* m' N8 z7 o4 h

# [, B: j4 I5 X% ^                for (size_t jj = 0; jj < vec1.size(); jj++). y3 \! h0 n- b3 s& R$ q
                {3 I' Z% x! D( a8 J, G0 N+ n
                        b1[jj] = vec1[jj];
( \+ G. e5 {1 q; G                }, \5 G; o# ^9 D2 T" o
, j7 |5 J; w3 ?& B
                for (size_t jj = 0; jj < vec2.size(); jj++)+ c, W( Q# Z+ D  Z: |( F
                {
! \+ {4 j3 |& O                        b2[jj] = vec2[jj];
0 n- k* |& ?' L4 `, o; a& v9 R! k                }
2 Q+ t; g% x& R  L0 S+ s
2 x/ I6 K( w4 T0 b. ^                //Method - 1  N=100000 247s  
2 y0 K7 L7 {8 W7 R                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);0 V: R  F/ ]5 }0 L+ e) U% H
                                3 z  L& V- O: l( |
                //Method - 2  N=100000  237s
& L" b: m4 z8 i; u- e                /*; j9 k3 m& b( f5 `2 C3 U5 W6 k
                for (int jj = 0; jj < N ; jj++)
9 F' i! ~0 D3 b0 |3 T                {. J0 I9 s( k' c! j+ B1 t, S) M9 X4 p
                        fresult += vec1[jj] * vec2[jj];% X: t( r  J0 g" I1 D( U
                }
+ G; M9 j- H  ?' [                */
- q/ N) C9 Y$ \0 @                                
/ s  n) a7 h* D' i                //Method - 3  N=100000 204s
( ~" `; b6 o; r2 S; U; a* f: e  s                /*3 I6 W& H4 }* _' o8 f
                for (int jj = 0; jj < N; jj++)
; p6 @( M* W! u( [4 E& @                {  D4 t/ S+ S% s0 ~  F
                        fresult += b1[jj] * b2[jj];) G/ {5 H( x; k* E- }  p  r
                }
% Y& I6 k6 g" \+ y, W                */
* `! W/ l' [- u$ y+ G( l3 y9 Z
: \  Q: x2 T/ o' `* C                //Method - 4   202s* M0 V/ b& K; p1 Y% J, u) ~; F& s
                /*
7 V3 P7 e+ [; |3 }7 r                for (int jj = 0; jj < N; jj++)
; t* K4 m9 L) t, _0 D, N) {                {2 p; Y4 V6 }& x3 s1 J3 H
                        
- m. ?! }- t4 Q. E$ u                }8 V/ b9 O3 @& ?" v2 d% f
                */
" O. ~" Y  E' x1 b) Q: q                //comment out all methods, N=100000  202s                ' l" m+ ~9 ]" u6 l
        }" W% e0 O* h1 Y
6 F, ~. V* a7 B6 J9 k
        delete []b1;
" V; p7 p# t9 Y+ x) K$ q- N( k        delete []b2;

5 p3 @5 ]5 U0 |" `7 W& h4 x5 n
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
2 `& y# W/ W# k8 b& n$ h: L: |. b& u2 }
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?1 P* t+ b5 \0 ]; @  k5 j4 r

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15, I+ u' J4 w. Y" C
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?0 ^/ p7 i% K& ]4 X

; B8 ]  p0 E, A2 W; s7 y" N, G你第二个试验里面的j在循环里面又重新定义 ...
2 w3 O9 f% `* h0 n
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
$ |& o0 l4 [7 N
+ e! x7 H' y4 G: j不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:165 s) |& N6 a  E- C4 y/ r" g
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL$ q1 a6 M/ R4 b' g" G

( P. V! m; G& o- Q# c+ H不和它 ...
9 |: a$ X& f4 w1 C4 G1 ]! K
/ _. J, N: Q" l5 x9 i
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
' l: @' q7 ~4 K8 z# u8 a后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54! p) C  a5 r  s# P$ H) \+ b9 e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ j% D% o3 o: p{
1 |- d) N- x$ v! D) w        comp temp, xtimesy;

3 V7 g. H$ F8 P1 {' F( N, j这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。8 m. ]) d. P3 }9 ~) Q& q4 F
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?; z# D* x  `' n' }8 e% b2 C
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
# G( u' L3 A  b2 r- L' R" X  W理了理思路,重新做了一个测试。1 X- N' k& k6 j3 u( s, u1 r
做了两个 vector 和 两个 float *, 都长 1000000 O* {2 K0 \( W% m1 z4 w. P
外循环 6000,里面先做随 ...
5 P5 l3 y6 w: g: O7 o
这个时间是从哪里开始算的?0 I* n3 T# p7 S# o$ g5 B
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
9 P- t4 R6 B2 k' G* d# @7 C按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:394 {- e, Y6 I+ N. C( ^  B3 E9 n
这个时间是从哪里开始算的?
# v  E9 j% t2 Y我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
' B% A2 H% u3 T4 m
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。  j- x+ E4 r0 N3 Z  c
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。) c) G( F2 _6 {0 s' S# ?1 B  o
与此对应用数组(指针)花了2S5 P: D% c8 J- m
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
. \5 I  T0 M7 E* j8 h5 v/ D& Dvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( ]# k( f/ ~- x1 y2 _- b0 C{+ z7 X0 X4 s' \7 S: R
        comp temp, xtimesy;
9 I( i0 {1 \# `% t
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗1 L: m: u/ l2 b) C2 w

6 R* [9 j- _* C. I: S
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
" Q: R7 B# K$ x" n( {9 h我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗  r+ @3 ?* v. @8 f6 ]9 r
7 E7 d; R3 d; Z1 D* w
...
" X) F5 P" v7 u6 `: t0 r
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
+ V+ {4 |$ u. F. y! B* [7 g7 O" @0 T! F% L. j, o' s# Y7 z
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
, _/ z3 `% u& o  O5 b% b' ?# E! I
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
8 q& ^. i: `  ^7 g" v有空时我会试试 SIMD和并行,看看能提高多少。
- N5 i( b; M! O4 m过去7、8 年没有正经用C++ 写过东西,没有 sense 了 0 {! P6 o, `5 h/ E
谢谢大家的讨论,I learded a lot.  红包已发  * O2 D: ^* `6 r& i

% M% c1 w) }0 @1 l. r2 k
: m( f8 ?7 P) v/ f4 Y: }5 w4 |  {0 j& ]% r7 ~

3 w0 ^7 K; q  P1 E, T7 \8 ?0 G




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