爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?# D$ c/ i$ Q3 p+ ]
$ G6 W* d5 f2 L" X& j0 J6 e% c
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。& j) ]" ^# h& b9 h4 C

' l" w) ~! R6 }  j" m. B2 h速度优化问题真的很有意思啊。
1 j! @# U/ l: Y+ ]% m: Y! W( t2 t+ B9 o$ y
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?$ p! d& o  ^, [! I+ r
把代码贴上来看看?
* P5 P! y1 U& N
4 h3 k- g1 [  v0 s5 g难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
( a' m6 q. z% B, ]9 z) t0 F
数值分析 发表于 2022-9-24 23:044 f( |4 ~8 J9 S' r3 u
拉下来?拉多少?
( i+ n, _1 u* }% s" E1 }: i把代码贴上来看看?

6 C8 `7 h# d" C+ {; M; U. v1 ~+ T; g# j. f0 `
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)2 H* u0 q0 w6 s1 T1 \+ u$ ?* V& c
{
0 t( B' F6 J' H; [4 Y5 w0 |        comp temp, xtimesy;
! e: X* P- `7 F3 ~2 Y2 R        xtimesy.re = 0;% o# [  q: \* _4 v( e% Z
        xtimesy.im = 0;5 x4 A3 }& E, t( Z7 _8 S7 Y
        int j0 = lenB - 1;
: F9 E/ |, J: [# x        int    i, j, i1, reali;
  o- \, i+ ]- Y  j) X        if (lenA % 2 == 1)# j* j6 @- H' `7 \0 I$ t8 w6 |" c& u. T
                reali = lenA + 1;
4 q8 z5 i& M1 C/ o; ^        else
( h! m) y, t* @                reali = lenA;# [, w8 {3 p  a
        reali /= 2;/ @4 x: B6 J3 E$ S  ~) m6 m

+ b1 K! G  T/ S  m/ R% B        int nconv = reali + lenB;
) Y7 V" _1 r: l! B1 a1 d        //#pragma omp parallel for
+ n. Q/ e0 L' y3 ~: E        for (i = reali; i < nconv; i++)
5 x# p0 Z' K/ M2 ]        {3 V; }; y+ p8 u1 s; s% t- R4 m, c
                temp.re = 0;
! E% B4 z* ?! N7 h                temp.im = 0;
1 M, d8 y  [' n# t) P                i1 = i;
$ G+ f! @6 g8 @8 R7 t: [) h8 _                for (j = j0; j >= 0; j--)
& N3 u# J2 Q! j4 f+ ]                {* w  ~$ k3 d6 \# M- C/ N3 h7 ^
                        /* floating date operation */
# x' t7 u/ U8 [7 ~- Z2 \; s                }

! K' o7 X% J, P0 R        }
+ g1 r2 D; J5 q}  M7 H, ?1 z' |* i- y

/ ?' d, d* n* v6 l" Hxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
1 M4 Z$ x, F% j2 e! `8 y/ E- t. Y) M7 F- _/ w
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。& K. E& v  A+ \5 ?( X
现在call xcorr 100次,耗时78s.
7 I, X7 J2 g4 K2 x) Y9 Q+ `$ o# q2 c$ B# B, L& \. k- ~
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
* e( H* P3 V  P) [1 S0 s
, y1 T7 [0 q( A" J/ ~
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
8 g6 e, t0 Q2 Z3 ^+ W6 l( OMaybe Debug mode?
$ ^: b0 o9 d/ a6 p* W

" F. I: J" D, f% n$ j不应该,看我上面的回复。
6 c4 d- @$ a: @% f6 W
8 \# Z: M+ W% K我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
  U, @3 w/ ?6 w. b3 B
雷达 发表于 2022-9-24 23:545 q3 G+ u9 }0 m$ h4 F* j
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB). q: a0 \# g4 O* _: K& h" t
{
& r' G4 {' j2 Y5 m9 @        comp temp, xtimesy;

- Y5 @, M6 k0 C/ x& {  T& K( V
: H4 N$ d" S, ~4 {, [& f这个不是这么比的吧。。。3 ~; F) R* h2 W: B

* E2 Q( Z8 c! l# R5 X2 p/ ]- ]您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
8 S. L& L9 w: L2 A7 u
. ?, Y5 N/ N4 _, {5 |3 Y而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 6 N+ S( ~5 g, z+ c2 }6 i
数值分析 发表于 2022-9-25 00:20& W% X% L9 b  Z1 I5 N" \
这个不是这么比的吧。。。
3 J- x  O) z; w8 ?
* ~; P1 G' }$ t5 g. y+ c您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

* I; Z" |  @% _1 p' S$ H0 q. t
  N' h0 e6 x5 s有道理。: ^! R/ q2 G* Q2 z
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
$ ?0 `  L) z* @2 Q! e5 g+ S4 D; w8 K; F$ e2 |* ]
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46* H1 u3 D* k1 a, |
有道理。9 t' v, O: F1 {! ?9 w
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
0 ~5 N1 i, k  b! n! c
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多2 q- y% R4 u/ R' T" _1 K
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
" h; \" W5 G1 a; w4 I这个不是这么比的吧。。。
( O# q/ g1 ]0 l% r
: B% G* d5 x9 Q% N$ h您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

! y  ~& i- J% I* {8 b3 j
$ h7 o7 L, D0 z; X  d. O$ M* [, G现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
$ k' s9 n8 @  ~+ d; I' d6 L
沉宝 发表于 2022-9-25 01:48% \/ _) l  X2 D1 \
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

) B9 ?. l. q" z) c1 I, x, M5 v) P! |& R; K7 ^, I* n! S
是的,兄台说的对。  _% R/ ?$ h. m# V, n' ?9 G7 e. ?& b
9 I9 z. [" o. }' \
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。& `% {! Y/ I  ]3 p

! Q$ _; @8 c3 ]% `- P雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。' g+ X  u% G) h2 b  {& R+ S) N. ^+ n
: \# b5 L7 [2 x: |/ T# y* z% F) Y2 P0 }
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。4 i7 H% Y1 C( Q7 N
9 _% X3 c9 H) y
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 - c; B4 H* C% ]- Z
沉宝 发表于 2022-9-25 01:27
. w" a5 t' l, R你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

5 a- ?+ [: W9 c2 ?- L" c, s! w# v) |' [+ }& Q  b0 A3 \9 s. R( a
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
+ k/ V* n; P! R3 J/ U+ k  Y4 w
$ p- Z& b/ t" j8 N8 u& m$ G* N$ M5 g( f我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
6 o2 R+ U7 y* C又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

' e4 y$ T3 }5 `- O2 u3 a8 A时间差一倍的结果可以接受。
$ y9 S. V6 y: A5 i( S
* q, ~, B; t8 [, Y8 [7 A你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
: ?7 l7 a) v: x  I/ c* v
雷达 发表于 2022-9-25 04:47
% O0 [' ?5 Y* V9 D5 J又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

2 a/ F. P- D! L+ F8 \" ~+ V4 ]" i) F2 g
( n5 r$ H/ B8 m8 b3 z: c

3 f/ v: Y+ Y& V1 d1 r+ w7 t能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ' i( g3 Y: f# P2 h; V  G
数值分析 发表于 2022-9-25 14:585 F3 n9 V8 r$ ]) l+ x; h! F! B3 `
能不能把这个也贴上来,看看和上一个有什么不同?
7 B- I9 l0 }$ s3 P  P
理了理思路,重新做了一个测试。4 j# p; L3 j# d8 v
做了两个 vector 和 两个 float *, 都长 1000000 T  i0 G9 x0 I" e; k
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.4 d9 ?, m6 b* h) [) u+ h

0 g7 l/ E2 E5 |0 _0 n0 z3 w2 Q内循环试了4种方法,
/ U: k" I2 R! y! R; K( D+ {1. 直接调用 vector inner_product 247s
. C1 L5 U* C! ]* R  `" s  m7 G2. vector 循环点乘累加 237s
. _2 Y( l8 h$ V3 E1 t. u6 Y3. float * 循环点乘累加 204s+ d9 ]' U4 a, G2 O9 B
4. 空循环 100000 次 202s
  U) q0 Q  T1 ]: k3 j) `. k
0 |. f# O, b# e' ~7 [  L4 n不做内循环 200s5 ~+ z" _" g/ i/ ?9 q! w

5 p4 ?9 \; c3 }6 t4 V% B你昨天说的对,内循环本身占比是很小的,大头在其他处理。+ H# ?% D" I6 ~: e
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
7 ~- |7 u/ g& [" D/ G
/ n! ]  W6 G$ c& S" L& z至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)  P; y* Z  b2 ]1 e5 J
, X' p0 c' ]3 N
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)& G0 n8 Y" l# G6 w! Q
0 X# x, I, q" b; Q+ x8 R( q1 |
        std::vector < float > vec1(N);
* x+ t- L% |2 V9 f. E        std::vector < float > vec2(N);! ^7 ?& }+ h3 f# N" W9 g! O
        float* b1 = new float[N];1 J' ?( U# b% v; S( v* m
        float* b2 = new float[N];
& p1 U& Q' l; \% [0 j6 l
# M( ?/ p' B: q& F( z* @$ n        for (int j = 0; j < 6000; j++)
! f7 t" Q/ b6 k& ]0 c. g  O5 w        {
5 ^& H8 K( M9 _& T6 `                std::generate(vec1.begin(), vec1.end(), []() {
. z* @( V( L* S/ t                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
4 x% R" C+ \$ S, ~- @5 i' C' O                        });. x. `0 w" L; Y; Z! K. ?: B' ~: J7 ~

8 r" S1 F* f. l0 T. F                std::generate(vec2.begin(), vec2.end(), []() {
3 P' s) c( i0 W; a                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;& s* T6 j# h2 e2 m0 I
                        });9 O4 R+ p& X2 b

$ H* ?# |. ?8 [$ x/ X                for (size_t jj = 0; jj < vec1.size(); jj++)' K1 f" q0 S8 U! M# E' P" F# ?- b# A+ z
                {1 [! @/ ?% r1 O# }
                        b1[jj] = vec1[jj];
' c) \4 R8 l: [: k: z                }, a6 h; O8 Y8 ?$ c: u6 ^
9 m& T3 a1 {4 P6 @1 t( I9 V
                for (size_t jj = 0; jj < vec2.size(); jj++)
5 T  ]$ H! V5 ~: ?. Z                {
' Q* A. p" D& U) T, _! O9 d                        b2[jj] = vec2[jj];
  a( K) `( v) \: s' Q                }: x  j( p1 Y. I1 E/ n

( o9 X( O* p) q6 r# w                //Method - 1  N=100000 247s  3 E7 P0 I; M% f
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);/ v3 ~) N1 ?: U2 v  N
                                
3 N6 b% S' R! D* q4 L2 c                //Method - 2  N=100000  237s+ s1 S# }6 h4 K- m- X: t8 o
                /*
! P' i6 f. ~8 L) {+ q/ d4 K) z0 }                for (int jj = 0; jj < N ; jj++)+ p" d( q- [3 @  j% s# o; d* g
                {
" e2 g, Q. x8 I, `  A                        fresult += vec1[jj] * vec2[jj];1 b6 @& V7 n6 ~3 h: b
                }
) k8 ~# v- m; A- G% y! Z( I5 {+ k                */! g- O" {0 p" `) J0 K
                                
  [, n' F) h5 W8 J8 F                //Method - 3  N=100000 204s; F' y0 ~6 ~  ^; w' k: i% t
                /*
4 `8 l. d! R/ F/ ?" L, t& B                for (int jj = 0; jj < N; jj++)1 y" B& g5 V6 V' a2 ~! t
                {% `3 P* k% a6 M$ K6 v  h+ i
                        fresult += b1[jj] * b2[jj];
% \6 o' |, Q9 Q5 E                }
7 K( {* j3 m' N! }+ Y- D8 G                */
7 c* N9 H4 @% ^2 t6 w% w# L
5 S  Q- N3 J. F                //Method - 4   202s
. p0 ]# [, m& d% x# T0 Q" ]                /*( q. f  i* \4 L% X8 J/ `# Y
                for (int jj = 0; jj < N; jj++)5 V4 E4 T; X+ m" \+ B2 S( w
                {
# j) G6 q; x# `4 [                        
6 v  U3 v% C) [% S2 J& l4 N3 ]* i% ]- u* P                }/ j% n, y6 C8 m7 _
                */2 n! |& H* w* R  U
                //comment out all methods, N=100000  202s                3 q5 J! U! s4 A. O: d( [6 c9 O
        }
$ J+ g. y8 v3 D, S1 O" }) N5 W, q  y  c, M- ?4 @- V1 T
        delete []b1;/ d# l  ?: P2 M7 S' j
        delete []b2;
- q; a' ^  U- K

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
7 h$ w7 B. p' d5 D- Q( `, E+ w* ~
" t" g: E# P7 j' o0 g' o8 b$ P+ o你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
5 S: |# O; v1 d) P
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:155 }9 z* p1 l  H1 v, }
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' h5 v- [3 `, ?% A0 v1 I1 D+ u
6 B4 _( u1 E3 U/ B5 ?你第二个试验里面的j在循环里面又重新定义 ...

; [# o" b! z; Z6 l. Z内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
" g$ x7 h; S' [0 |2 S, ?$ L9 T4 w% T( L8 I
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16! K7 T5 p* W3 a. g8 u$ O
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
% T) D0 L% A& \' z4 F8 n" T; `% n9 p% c' U; B$ p
不和它 ...

5 I# x) O3 X3 l; j% s4 S% k) M" w% h5 J+ ^
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
5 ]( }( Z1 f; J后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:549 l4 ]: c6 ^7 [; A7 [$ ]4 X3 w2 A
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 d1 \/ u! y$ q{  s( y1 I1 @! m: ~- ~
        comp temp, xtimesy;
6 o% z$ E( t$ u$ l( \% w8 {: T
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
4 `  q( t/ E$ v$ B! u2 v内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?9 [! R, C, o: f: w2 }
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30; h9 G, q1 ?  |" k9 w( w
理了理思路,重新做了一个测试。  }" |; L( y& {& D
做了两个 vector 和 两个 float *, 都长 100000+ `' P5 Q: ~7 W7 Q" P
外循环 6000,里面先做随 ...
% O; o/ w) m( U, Q/ }4 e7 k
这个时间是从哪里开始算的?) y* A! N) c  Z# W7 ^) X
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。6 U8 y# K; X* e' m" D2 ]6 Q
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
" `$ |: s8 O9 `5 y这个时间是从哪里开始算的?
( |9 e5 e& Z/ [- G/ a我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
, U6 @6 G" l0 X1 K
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
- m/ u) O5 R* P+ b: ~你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
% K5 W. E2 I" f, W8 ^& i0 @与此对应用数组(指针)花了2S* Z0 j" m9 ?2 f3 E, ?
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
3 m/ k; V$ t5 ]3 E2 _; f0 cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
2 I/ W2 G0 r9 a" P+ V$ ^% ]{
/ t- I6 l' E. N0 M        comp temp, xtimesy;

) i7 Z% r9 O& |* \* s& N+ F我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗3 P. ?3 s. k& H
: u) k) Y; X! d" q' `

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
0 I1 k5 s, O4 B. l! b5 r' Z我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗( t  D3 j1 z5 R6 {
. H' P" F8 H- R& }
...
; a2 b) k! g+ @- i( k
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
, k( B8 b3 C9 r; g" \5 d) k% S+ @1 x) R
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 / Q0 h! l5 s* j. M
  Y- A4 E6 C$ o+ C; [
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。8 r2 T6 s, ]) e( C  v$ ?
有空时我会试试 SIMD和并行,看看能提高多少。
* h- I, `% u3 ?) h7 P过去7、8 年没有正经用C++ 写过东西,没有 sense 了 " T' G; S$ Z; I) l5 ^8 N8 T2 `
谢谢大家的讨论,I learded a lot.  红包已发  / G& ^1 _: a( f& m
' v; a8 a. W8 [/ ~, M

1 |  c# C  I4 e
4 V/ R$ w% J9 p) a# s9 Z
" C0 P5 s# U, `' P% z3 y5 }




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