爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
8 l- Z" R) M3 k( Z) n
& Z# }0 x+ }7 v7 n$ L* l/ N自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。+ t: M. x6 X. Q& g' ]9 b: \
' w# ?1 A' j+ ]8 ]( u; K1 |
速度优化问题真的很有意思啊。8 a8 O6 ]4 i5 o
8 g/ k6 N6 N& U1 w) ~6 E
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?: F1 g6 g/ ?6 `* ?
把代码贴上来看看?. H1 V2 k$ W4 b& ]) j

4 _* J9 q( ?: a6 [难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
3 S9 w% U0 J: c) l
数值分析 发表于 2022-9-24 23:04
" K# g9 x% o9 m4 s8 s/ l拉下来?拉多少?
0 s6 z9 c9 o& ]4 o把代码贴上来看看?

& i" U! P7 d* @: H5 Q7 Q8 O/ M
4 g0 Y+ H" X. z, Ivoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB). G. M5 m. e, l' A7 j+ T
{" X6 [' @( I; H3 `
        comp temp, xtimesy;8 D* ?5 j( o# R; V* y$ V' G" e
        xtimesy.re = 0;6 g2 _- H/ Z# S' _& t2 P
        xtimesy.im = 0;
+ p6 P6 Z' ~: C3 U        int j0 = lenB - 1;
7 q, p; h) C4 m* K4 I5 j% l  k        int    i, j, i1, reali;
( o- h& q( Q& f% R        if (lenA % 2 == 1)6 K/ N  z1 W( n
                reali = lenA + 1;
2 v/ h" m- S  M        else0 N5 f8 F" K0 X/ ^- q& I* O
                reali = lenA;
) V1 ~- C: }  U% r( }" s0 ]2 o; X        reali /= 2;+ R2 A) H1 L( z
+ R: i5 k' l2 T: P! @
        int nconv = reali + lenB;
3 k1 M* v& s/ l5 b5 q' B        //#pragma omp parallel for# p, B, `5 {8 t$ |
        for (i = reali; i < nconv; i++)( }4 Y9 e+ v, \! l: M4 E& j1 R7 L
        {
: g3 Q5 K& K) ~; Z9 {* m4 J7 l* _                temp.re = 0;0 l6 l# ?0 u& b! ?+ C2 {" g+ K2 r2 E
                temp.im = 0;
9 l1 |. T' N# I+ }, c1 v. s# U                i1 = i;8 Y6 b8 ]( n' t
                for (j = j0; j >= 0; j--)
# A% F4 i. b) [5 v6 |                {
, |. H% H. T" _& n" Z                        /* floating date operation */
! D4 T7 F4 H2 {+ [# R: O+ B$ b                }
; X3 d: O$ c( I$ D4 E) ]0 k% n
        }; k3 X1 g( B- w
}
) ]* g& c- Z' W& N0 I
, X0 U7 g! k+ Rxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样) B. J. d4 Z' B! n4 E) |
5 D: D+ s5 {$ Z$ ~
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。) z* a0 w, u6 d/ `# Y6 k( t
现在call xcorr 100次,耗时78s.4 m3 v/ X7 }- P" X* ~* {

! g  `$ x4 z/ j1 o如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
8 s9 A7 F1 R; h- e; y/ @! Q* d( o7 H# f! Q9 w4 M

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
" c) ?1 f7 L7 D4 ?# E' wMaybe Debug mode?
% J6 C+ I2 D9 u( X/ i
3 x' N3 l0 o- M4 C/ ]/ ^
不应该,看我上面的回复。
# \5 U$ g$ Y- I% y
: D6 s1 K4 x; D2 q/ _% ]( V1 ~我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
0 t1 u% i9 q! R" ^; U, y
雷达 发表于 2022-9-24 23:54
% q$ o& C1 [0 K  ]1 X0 Yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)! E# ~' f/ G% j; d# k& [, B
{7 x+ {2 j" x8 l5 {  a1 K& |
        comp temp, xtimesy;

, b$ a9 n$ {0 v6 u' u) }# s. P/ x0 h- }2 N$ s. c# ]( [
这个不是这么比的吧。。。
' w) j5 t/ M% i6 ^& \& Q9 C( C+ }
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。- Z2 a; z9 Q0 g2 R3 Z# V. ?

8 w4 d7 x3 J1 l, T5 P. d而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
5 G* J; c2 O* Q/ M! T
数值分析 发表于 2022-9-25 00:20
$ W/ q5 p4 I; v! I" S- h! X这个不是这么比的吧。。。
3 b5 O4 r* B/ f+ Q) W, A8 ~# g! f; j1 c" Y6 a# p" e5 R
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

9 i- {8 W$ f/ f( h) @9 V: ]& t: A6 |) S: q; h  Y* n
有道理。
8 F& c0 P, f8 }# \* m" J所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。- X) z( [- s5 _) ]* d
/ f6 u! B6 K1 K7 M: e0 _
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
6 g; `. l: N0 X8 c. U* _7 Q0 b1 \有道理。
* W! D) U1 u. Y# n6 W9 g所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
7 ^8 a6 r- F8 j  y
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
/ u# n/ ?! T! F: R( u& uWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
: V4 m2 M% F$ ^, g' s, Y' ^这个不是这么比的吧。。。+ \5 O: Z1 o1 E$ ]
6 _( h: Y8 F+ M' P& Q
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
5 M8 J/ T& y( c6 c

0 z# ?4 A; K: ^$ D* M现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 2 S. x4 g# _) T$ C
沉宝 发表于 2022-9-25 01:48  y" `- G9 w$ f" w, j' R" K4 g
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
, j) Y% ~* S* Y# m
# c$ `/ Q: r6 w
是的,兄台说的对。8 n2 e/ p: v7 q, Q

' @, ~+ v3 \8 b其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
$ K4 K) e+ x9 I4 c! h
8 p5 b5 L" G7 k" G! d* E雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。( G1 n; R" q3 X& V. p
) w* a! M" O8 B7 e5 a' `
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
( g. M  c% m; \, x
9 e5 Z/ q) K% a1 w! y2 ^当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 9 s+ {! H2 b: k
沉宝 发表于 2022-9-25 01:27  c; E- r  o3 S! u! V
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
: H7 U/ N( D% w# U

, k+ e; `! B- P8 F又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。( H- H8 N$ b5 H7 b1 L8 Y( w

2 y3 l8 \  ^' [: k我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
- B  t5 _6 A3 Y. @, ?( f又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
: W0 T; K$ u; \
时间差一倍的结果可以接受。
' Q% w% L- D1 v  m! T. [2 ^1 s, f
0 a, z, C% ]+ ^; `/ I- B& f你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
- h2 C1 b7 I7 |3 y( u
雷达 发表于 2022-9-25 04:47% q5 q0 u5 M/ z8 b! q2 N
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
- ^) B0 f' y. l6 z

" S, ^# K8 R  f$ k( P& b2 @! ?. l5 s# O8 z2 D$ T% |$ e; W

! ?; T7 |& e6 {能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 ~: s. T  Q* |( C8 O# h
数值分析 发表于 2022-9-25 14:58
3 o3 {! x" w7 V3 D, U, ^能不能把这个也贴上来,看看和上一个有什么不同?
# Z8 M: r, H1 A: }
理了理思路,重新做了一个测试。
0 C$ k' B1 Z# b% v  g做了两个 vector 和 两个 float *, 都长 100000; d* Z7 i" n" n
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
4 P* }  q$ D( Y3 w# M; P/ d7 L" x. i( w0 k/ R1 @
内循环试了4种方法,& I1 n! ~- ^* U( G! R$ o% V
1. 直接调用 vector inner_product 247s
( R, G2 U- x& R2. vector 循环点乘累加 237s
( I5 t1 @$ |" y3. float * 循环点乘累加 204s
4 ?9 x: n* I4 _( Q4 S5 C4. 空循环 100000 次 202s
& D$ t9 |4 B! k) k) `- W$ m- [
) n# d+ m  v5 ~9 w' ^/ m( Q8 B不做内循环 200s1 L+ v0 r: [- D
9 M) r: \- o9 Y( Y6 `. M" z
你昨天说的对,内循环本身占比是很小的,大头在其他处理。$ }' m5 b3 b+ I' B' s
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。1 ?# c; l* P2 r, k

- y0 p8 h( h9 m$ q5 O至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)4 d: f: X2 R# q( j) J0 y

, A- l0 c* r9 Z/ v1 g. j9 x" h& ](为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)6 r: r/ Y' ^4 A+ c# D7 w* P

. M' c: Q: a4 h% [
        std::vector < float > vec1(N);
3 `: _+ H2 q" S+ E: Y        std::vector < float > vec2(N);8 C$ L% j- o/ x" Z
        float* b1 = new float[N];7 H2 r2 N" U/ z
        float* b2 = new float[N];) ~* A, @# `' k' B4 y( r

2 N+ R3 k9 G$ X1 Z; W3 Y) R        for (int j = 0; j < 6000; j++)
. L% \) P& U( G, I" ?/ K        {
, K# a  J  N; T- z) b' j/ w                std::generate(vec1.begin(), vec1.end(), []() {
+ \1 X$ R8 L2 o* C9 w                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
: l5 L! T4 P$ N7 m                        });
9 j% Q1 i0 `6 Y8 L* s7 v$ P& B' Y' {. U, p+ |$ c9 I
                std::generate(vec2.begin(), vec2.end(), []() {
% @0 s+ I" c- v8 D' u                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
* d2 O7 h$ w' B( E) L) Y) n                        });
, R' U' w$ j1 L( B: L; u; G
, D. L, M: n# s- y1 n; W                for (size_t jj = 0; jj < vec1.size(); jj++)' K. ~* u# O  y6 l1 T. R; ?. }
                {
: ?* ?2 C. f( D+ ]2 f  C                        b1[jj] = vec1[jj];
$ c1 ^' a: C9 N1 ^% @1 l. E                }) n4 s! V% m- y  }7 t/ I

5 w) M+ q0 H# K4 u& s" F                for (size_t jj = 0; jj < vec2.size(); jj++)
8 \; G+ b2 k' M0 M' l) s                {
: t* L6 B. C( ^0 A" J2 I                        b2[jj] = vec2[jj];
9 `; l0 W. K: C$ g, @6 n                }
1 K0 {8 u+ U& c) @
8 [. Y' F+ G' N2 m% f                //Method - 1  N=100000 247s  
1 V5 G  c+ N' C                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
  c2 Q' V; y6 P' Z, L: q# P                                
  ?/ h! F8 g6 W  g* i4 l# g( h                //Method - 2  N=100000  237s1 P8 m# Q  D: u! U  r$ v' ]$ I
                /*# Y0 ]6 S- R# Q" e- d
                for (int jj = 0; jj < N ; jj++)4 G6 m4 N1 U5 C( @
                {2 x& g9 t: D) P& A# P! k
                        fresult += vec1[jj] * vec2[jj];1 V1 D7 j* M. P! J8 G5 v+ y
                }
4 u9 ~* a0 Q: C/ c4 g6 A) u+ Y: C                */
' m9 ]. b" ]: e0 x- s3 X" m                                ( ?' o+ B. g; q: U( t2 P
                //Method - 3  N=100000 204s
+ |4 P$ R8 f2 P; D  N. }* f% S                /*2 G- I1 v  ?6 N8 v6 l# V
                for (int jj = 0; jj < N; jj++)) p. f, Z7 \- W0 t
                {
# m/ L( X$ |3 D8 G: j! m7 E                        fresult += b1[jj] * b2[jj];$ d7 a5 b! V: N) N& r' u) ~+ X
                }5 ~% [( |( c  l, l! F
                */9 q2 ^& I9 ^- ]% b- x! Q

$ h+ y9 m, g3 F                //Method - 4   202s4 O6 d' V/ Z9 A8 W
                /*8 k. D) q: ^; r8 k
                for (int jj = 0; jj < N; jj++)- P& v4 K2 y: W* Z/ ?
                {- q1 i3 I- K2 c
                        9 b& E. D) ?) x8 e
                }
% k) J6 g/ X* h  ?6 D& |                */( f- v% @; E( A! d
                //comment out all methods, N=100000  202s               
4 f8 Y; u6 z, h  O        }
: r! U: l6 Q" }$ o0 {' d3 U% B" |! p$ b* N8 ?# u, l( k9 H, Q3 r' w
        delete []b1;% ^5 _. M0 e3 C
        delete []b2;
% e/ k& Y& ~. N9 M, ]1 m3 E

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?8 v1 x  r9 `  E; I, d4 ?
; |8 i" P: c8 S6 D/ R" Y: \
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
5 ^( m' J! p8 T- O; c9 d, p9 l3 t
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:151 ]! b3 `. x1 k
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?: X( `: S' ?" A9 F, x' ~

% r5 ?% T* G) F' x' L& L4 g你第二个试验里面的j在循环里面又重新定义 ...
+ F% J: k/ y4 j; Y, e# h
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL% [- s" D/ r* `9 I! X

* t" e9 c+ `" K, y4 n. s2 ]不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:169 [) U/ h( ~* D  H5 Q) `+ |9 E$ w
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
% J3 p+ `+ }0 f; c
* J$ S: J5 Q0 e4 k( S8 ^, |6 q0 I不和它 ...
4 X" n  }; C5 h/ g( @. F% D

8 |  D& V9 x4 P2 s& g3 v% z不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。  b- U/ i, V1 W4 |# C
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:549 A  k2 v% o3 ~/ Q( r$ X3 T- l
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 `' U; m4 N; y) k& y6 M
{
) b( D' e+ }2 p: o' `6 {- C# z8 J        comp temp, xtimesy;

) C) z5 f  N% x: B" \" w% _; O这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
% b, t4 y+ g2 U8 t7 G内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?. v' f4 R/ I. r
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
* k2 E2 |$ A1 B. l; G5 q理了理思路,重新做了一个测试。
) K! `: A$ K3 P( `9 B* w做了两个 vector 和 两个 float *, 都长 100000/ j1 G+ ?/ t& h0 V
外循环 6000,里面先做随 ...

5 h, n% v7 K" f3 `' ?# Z5 c这个时间是从哪里开始算的?8 N  E- \2 t. u, \/ `% w0 H
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
, S7 ]1 O" E/ w0 D8 D" g按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
! Z$ |/ A2 D* u! P9 l7 C1 ^: {, Y! A这个时间是从哪里开始算的?
" r# C4 K6 y5 x& e  @6 J. p0 R, u我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

; G7 i& m5 c2 u' n4 _$ ~3 t我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。1 ]7 \: l* @: V, x
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。8 t1 C) f9 u4 I6 |1 T! @9 o' e' d$ A
与此对应用数组(指针)花了2S1 C# {! ^" o; W
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54- e( U% w$ ^# |( {$ K- [$ N
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- h, j% a8 g! o$ l0 Y6 c, i{
- d6 ]! |5 f' x8 m2 h$ s# K; g        comp temp, xtimesy;
% e* @* N: |* `8 U! X( h
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
9 D- X  S' |8 U( C! @# y* O. Z
! ]4 U/ ?6 z- {+ c
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29- Y% G! C# }, m0 A4 K+ A
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗& A* ?% N" Q9 \$ f6 p- ?

  X7 a( E" }$ C" W, p" { ...
% A# \* C3 M" M: Q' N- G5 U
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。8 w, s. e* T+ p
+ r9 @% y2 o7 p) g; z( j  C
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 5 u- G" x( D8 K4 ?8 p- O
. g  Z, s5 ^/ t& z3 S
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
- R) D7 n4 s' j; d有空时我会试试 SIMD和并行,看看能提高多少。! O! X* y7 Y8 s6 R6 x8 v6 r( [; Q
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。4 X& G& p, c# a% l; v
谢谢大家的讨论,I learded a lot.  红包已发  2 e2 b, L4 r, e- |( U
# _0 i( F* ^3 ?
' w' `7 D* ^3 d# D/ n% Y% l
& b% ?- X) Y* B! l! N
/ m4 m3 ~+ [* ]$ E* Q' H





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