爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
, Y% b* x8 a8 h5 i1 U& ^2 g
! A, B8 O. M6 O: O自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。" e2 I. v' |7 I2 B- l
! z- n+ r  d/ o6 g
速度优化问题真的很有意思啊。
. D0 d3 `! s0 O0 _& o1 ^
2 Q" w5 e& L0 ^( L! [: P3 K欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?8 Y: S  Q1 T: b) p
把代码贴上来看看?! w3 J" e- X0 b: t. W

9 `2 w$ g' _) S+ F3 ]2 ~4 k1 d难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 9 y4 G* A8 w* {- x8 _4 y5 r  u" `
数值分析 发表于 2022-9-24 23:04
2 _+ g6 L: ^. Z3 [1 l4 l拉下来?拉多少?1 j5 X. o7 ?! C' t
把代码贴上来看看?

* K8 b+ H4 c! X+ ]
3 J- J' ^3 f6 m7 y8 Gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)* o' P9 T: K9 R2 a
{: V9 u! n1 Q0 B& |6 ?9 v
        comp temp, xtimesy;- D( L, @3 E8 a
        xtimesy.re = 0;9 a' Q  K  a' _2 v) Y
        xtimesy.im = 0;
* X* J4 Q" G! v8 x8 m) E* {        int j0 = lenB - 1;3 u7 Y- {' V4 @# v. r
        int    i, j, i1, reali;7 q; t* s- t2 F0 D+ o
        if (lenA % 2 == 1)7 B4 E9 [# I; c4 s* O
                reali = lenA + 1;
/ G  \) O1 Y  |3 a8 N* v        else
9 m( A7 e  p) G4 G                reali = lenA;: Z7 z3 \# r( C, Q' X+ S! O
        reali /= 2;$ ~! r1 t9 \7 C2 _

! @. F/ K. o) W) P1 J9 y  f+ a- o        int nconv = reali + lenB;
- u) W% F* m9 H        //#pragma omp parallel for
+ Y+ s( g+ N6 U' c1 [5 z- f        for (i = reali; i < nconv; i++)# x4 l# o2 ~% A- n5 S4 G% g7 w
        {
: _  Z; d+ b% `* P                temp.re = 0;; O$ j& ?( x9 M# e( F2 U: t6 [8 \! z
                temp.im = 0;
1 I. A- M9 U. y, V                i1 = i;
1 G$ ?4 C/ u7 v) {8 d                for (j = j0; j >= 0; j--)
# P* o; U2 G/ w                {
- ~* o, E9 y* O, D                        /* floating date operation */
- B# p5 z6 n. n3 o4 h! X: f: E                }

/ J1 h3 c$ B$ k3 I! _% u/ J        }# n2 {% L$ X; \: ]7 f& \
}
) b* q$ S" t, `8 x0 n% M: [' {' R2 Q1 [2 _- w
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
% m) W, [, Q) W! R) C; X% N" v
, Z" g4 w+ s* V/ }红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。3 T9 `9 f' h" d
现在call xcorr 100次,耗时78s.
% S7 K: q$ A0 D! S, M4 D# m, }
8 q  _" d; _+ N1 F+ j$ H如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.   }- Y' U5 S9 R1 B- i% r; d! Z

% @% Z3 r+ {4 l& M
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
! @, ~- l$ F; Y% b2 L; e' zMaybe Debug mode?
3 V" {# L1 R: j' f) @/ T+ h

* b6 q& C! D& F2 `: m不应该,看我上面的回复。
1 U: E- d% x: i0 B# Z
8 A& z- T, a$ P我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
2 q( W' e, I6 ^" @' V
雷达 发表于 2022-9-24 23:54) E" C, e/ S0 \* F/ l+ p: |
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)5 {- v: q, L* m9 O% V3 B2 R
{
. ?  X( i3 p" u        comp temp, xtimesy;
0 k/ i0 {& ]" z. g( J, m' F; U
5 ^) @8 e2 e1 A0 Y& c" F6 L( J
这个不是这么比的吧。。。4 N4 p* v( x6 S. a' f  z8 V

; @( F0 I* Z4 p! g; v您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
- e6 S( E) j6 Q- c- d& X6 y) c, ~- r3 r0 ]3 w
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 ; y. p  F/ W6 _* ~! t$ {9 X2 z
数值分析 发表于 2022-9-25 00:20. `1 \+ _9 Y4 ^' R9 S/ }8 ?& k
这个不是这么比的吧。。。+ K2 s$ a- T( ^  K) W/ E
3 ~4 `: j, w4 I! P
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
& v+ Z; r! _( I0 ]- M
- G+ C- J9 ^; q( ]/ C8 ^
有道理。
2 F# {* C8 ^' C- ]* N! n; G, i所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
" ~7 L6 E/ r/ Q% ~0 j4 L, C. n" C) W" K- ~: Q: N' R
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
+ C# W5 \' R0 f& U0 E4 D有道理。
: k- R/ v* x1 O0 V3 m% f1 [所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

9 \# w8 O7 l# `4 X1 P5 }你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
4 J! C1 c6 ]  PWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
6 A' c1 }, U5 H6 O这个不是这么比的吧。。。
5 j& B  E, F) i/ @# J, `* Y
, `3 p8 J  ~) F( {) V您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
) y# z* K7 W* p

4 B% Q  }- C5 V" N' j& I现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 # I) ?. {, e4 E/ }/ x2 S4 J, H/ t
沉宝 发表于 2022-9-25 01:482 K& _6 F8 U& ^" w
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

. t( W  m4 o4 o1 @1 f
8 W  B: [$ ?% V6 v# B( A! j9 K是的,兄台说的对。
# D+ a' ^. Y: L( X. c. d2 n! E# a8 \
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。, j, s% i$ S4 _, s( A6 x/ D  e

. R$ ^( W. f8 |雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。! @7 D* ?/ n6 o' i( r2 R! x' o
; c/ f2 J7 \2 v# Y1 O+ d
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。% D( j2 L* s* l. {0 \

. c" U4 _) h* y* \当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 , D( U2 K( x% b' J) m( V. O
沉宝 发表于 2022-9-25 01:27' i3 X2 g* q( f9 X0 o9 J0 B
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

6 H; Q+ g# \: T' U7 u
% K8 V5 ^* D: s7 w又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。# X$ Y2 j' H! _1 Y9 m

8 O# ?7 |+ z$ n9 M我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47: k: ^* l" Q+ o3 k' j% y. J# q
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

9 f& t6 S% c) b; n" E: q时间差一倍的结果可以接受。3 `6 C$ q1 t4 r+ j% o4 F! `
. H6 `2 y# J; M
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
+ e  t1 S' C) K$ d( r3 ]
雷达 发表于 2022-9-25 04:47
$ [2 ], o4 P5 J  j* a" ]  r又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
5 G' Q6 \8 }' n9 x8 b( f

# i, K/ ?( O9 e3 E( W  D9 Q% ^; b9 y: X: ^5 n* B& t& v- u$ a

; f" R/ b( j* K能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ( T, p" _) }2 h" D- Z, _3 j
数值分析 发表于 2022-9-25 14:58
8 X2 H6 O8 m+ P2 |+ `能不能把这个也贴上来,看看和上一个有什么不同?
# [. ]5 A+ A; F
理了理思路,重新做了一个测试。( N. c+ I4 d$ B  u: W
做了两个 vector 和 两个 float *, 都长 100000( I% J3 B2 L/ b
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
7 `  b) O. s, P! j* z! f4 e9 [+ y5 y5 u( M6 |. d( Y
内循环试了4种方法,/ S. _7 v$ _' ]) [0 p/ G" _
1. 直接调用 vector inner_product 247s 6 Z6 w6 W3 P/ l6 S5 G
2. vector 循环点乘累加 237s; _+ R4 k; O& F* x
3. float * 循环点乘累加 204s3 x. [0 S: D1 [0 m! O9 t" {+ l/ D
4. 空循环 100000 次 202s
% P4 W0 O7 G2 o# C7 E7 u3 I
) p$ N% `% S; i不做内循环 200s
2 `7 N2 C" e3 ?- f5 O% r: ?! R7 W) v  C0 K- O' i0 t" L8 r! R
你昨天说的对,内循环本身占比是很小的,大头在其他处理。* m: _% G, w* ~4 S- O
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
' `) l+ M( J. b; r* o7 }. p: |  L8 s/ O+ C$ L1 B- O$ h
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)' z# y9 b/ E, w+ L& z
5 V4 _+ `+ w0 ]2 [  d0 R- Y
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
+ {2 H* g, s( G+ r4 v4 g% T. Y8 R0 n4 n( F" s5 g" g2 g' e
        std::vector < float > vec1(N);0 E5 u! k& w  c5 z: N
        std::vector < float > vec2(N);0 \1 x* f+ e4 S/ C2 Y
        float* b1 = new float[N];
2 V7 F* Z  q; }' B: M! R; Z) ]        float* b2 = new float[N];* P6 l! H% d2 X$ ^( S3 ~

3 h( V3 X" o- {$ D! F; r: Y        for (int j = 0; j < 6000; j++)
6 {5 Y) @& M& ^3 |7 ^1 g        {# j9 w! n5 W1 B$ l' W" b% V" l
                std::generate(vec1.begin(), vec1.end(), []() {+ a& f6 |$ S* }$ D
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
* u3 Q- {8 J9 ?9 T: q                        });
7 S) H* _3 L1 i# {" J* r# @
6 G* A0 w- d) K0 v  u                std::generate(vec2.begin(), vec2.end(), []() {* B- D/ M* T4 V  m1 d& ]
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
$ |0 R" c4 o% I+ [, E4 r                        });- G; z$ ~: e; X8 r/ V0 _/ F2 o
: _/ I* f* }' s, N2 E
                for (size_t jj = 0; jj < vec1.size(); jj++)
+ n2 X" t- q7 I! j0 d/ p                {# v8 U4 @+ p6 A$ b/ H& V
                        b1[jj] = vec1[jj];4 r, v9 E; `. y7 r7 y7 ?4 ~
                }
% Q9 K  R6 @5 V: e% E% H, h& O2 D7 @- J$ O( s
                for (size_t jj = 0; jj < vec2.size(); jj++); g( S3 m" e) N0 U; v
                {
3 g9 |. N4 I4 i4 u4 V9 p  p3 v2 C, R                        b2[jj] = vec2[jj];4 H3 T) n  H( m/ k% p0 |& P6 f9 j
                }
( u9 x' {, Q6 P& z, g3 T
- A2 [3 P+ A$ c( t' r( l3 G$ ~                //Method - 1  N=100000 247s  
/ Q% l9 j3 w/ c3 _9 d/ a+ X                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);% T  X# o$ o9 {" R9 b5 s: W1 U
                                
' v7 T1 o( I/ n                //Method - 2  N=100000  237s8 }  S: Z3 D; {! _+ j
                /*. w2 l/ Z4 ~  q" J8 t
                for (int jj = 0; jj < N ; jj++)0 u$ a+ L3 j4 x: C/ q" p; N
                {
8 P" q  B5 w6 X! N, n                        fresult += vec1[jj] * vec2[jj];
/ U4 f/ o  J2 A; ]                }
, Z" `1 s1 X$ u  b7 Y0 D) u5 y                */: f) N( \. j, N
                                9 {* Z  a8 k- E$ I& l
                //Method - 3  N=100000 204s
5 N$ R4 Y& `+ B, V8 Q  D                /*
0 o' T# k$ O4 a5 V+ C+ ]( _                for (int jj = 0; jj < N; jj++)1 }% X! Z: u; Y0 o2 G& e
                {
6 d$ ]: P! ^) {* ]& A$ w                        fresult += b1[jj] * b2[jj];
6 E9 ]7 @' m, n" p$ H                }
, C4 C5 w" d! |5 c3 U3 c/ H                */- ~" T' e& h$ o4 @8 X8 ^

' ^" Z/ n: J5 m% p0 _6 W- x                //Method - 4   202s
- L; Y: N4 ^5 Z+ t                /*
+ G- S0 \" z6 ]: A2 i. d                for (int jj = 0; jj < N; jj++)4 X- J% d9 s+ b" t% Y# G
                {8 ]; W: i( q1 k' S6 ]5 ~3 l+ n2 v
                        . S# e  ~) J: _" j2 u  P( g3 |
                }5 o+ c. E6 }- a; A" m. C) Y
                */2 a5 Y2 C; t9 |  \
                //comment out all methods, N=100000  202s               
- I8 l# O+ L4 I, P7 Y/ T        }1 y$ V3 o; q) B" O- K3 a

! i* A0 {- \+ R' }- o: [        delete []b1;
7 f1 w, V, m, F$ p( p        delete []b2;

  _# y, D  g; @6 g8 p( X& t( A
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?2 I8 u1 X& X3 ], o. |9 A7 ]6 C
" {4 W( ^0 J: R' N
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?: L! Y' u% G7 Z  ?

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
+ z; t: L% r2 ^; \瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?, z% n+ u6 Y' a

  n1 p% }$ x1 j7 p, n你第二个试验里面的j在循环里面又重新定义 ...
- ]4 g$ x6 M7 ~% E1 l8 F6 m$ x
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
/ X7 @% w1 H5 L2 p1 |/ w( x8 l
# S, b8 ]  I$ L" t( X. T$ P* j! h: ^3 R不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
' d  m+ B$ W. T: h1 m8 O# m内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL$ y8 a  K) l0 I/ L

, e& s) G1 S! I+ ~不和它 ...
# Y4 u% z# G/ d# l. w9 {4 p

0 Z7 J( _4 t- d6 k; x$ Q不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。% {8 A' Z" Y" y# I0 L
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:541 e4 H0 [4 A" `% U, U/ y8 Z
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* }" Y, W( }3 m1 v{/ O; w. u/ a  K- c, w* R
        comp temp, xtimesy;
9 ^$ C8 g+ H; c9 @' v( g  @
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
' V! b2 y1 S& I% i9 z' }% r7 }内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
0 F2 Z2 N: R* U- B4 a+ W( B$ JVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
7 {+ D0 k' s( G1 E理了理思路,重新做了一个测试。
3 k) N9 L- K) R& ~' z做了两个 vector 和 两个 float *, 都长 100000, [3 m9 T5 P' G, h+ c, H/ P
外循环 6000,里面先做随 ...
( w: |, |+ O0 ~( T! L) b- d
这个时间是从哪里开始算的?
+ x- h* N( [3 b我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
6 V5 m# S' _) l; d+ w% }按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39( n5 O4 N: e  _4 C% K: q
这个时间是从哪里开始算的?2 z" c# C; Q( q, J- a# r
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

0 I3 t2 ]- ], B) B$ ^我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。' t& A4 ?1 D& A: b  h& Q+ }* ^
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。# n' U! s) z, k' x! X
与此对应用数组(指针)花了2S: Q4 X* V7 c+ p: W0 p
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
) s& c7 V/ X: [& H. D  Svoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)* k) i' b6 d8 C# Z# @1 s
{; R! ~$ Z: N7 R" \9 i1 ^  `
        comp temp, xtimesy;
% ~! {0 X/ g# o  V7 C1 U' o4 m
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
! m7 A$ ?9 X* W" n# F
2 o- s5 O( W0 I" R
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29( A& H  Y' X2 x/ E* b! b( D
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
. `0 W% M/ h) ]0 y' h6 H0 v: h& u$ W
+ T- ?4 k$ [* Y1 C ...
# W# |8 h6 k- J- y: o, j
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。0 [3 d. X$ X3 ~0 v$ U

( M: O! d; s+ x* x  U雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ' o# Z% _0 ~" S' |
7 _+ O1 s" n; |1 J' Z
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。+ c+ N: m" H1 N
有空时我会试试 SIMD和并行,看看能提高多少。
/ v8 e/ s% ~2 n% T过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ! ~0 ]0 u: L% k9 O
谢谢大家的讨论,I learded a lot.  红包已发  
+ [. z1 C, C6 n) U% _$ {/ j7 K" X' ^7 l

+ u2 t; V6 D8 }2 X- P' q1 d( c. z! K9 N3 Y! Q( [/ K& Y$ a) a4 [3 B$ Z

5 B5 o0 z0 e8 r9 w




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