爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
* I9 z, n& R9 i& O: v5 a' {
. L* Y$ X- ]- C% t# i0 [3 S% O6 R自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
, F. f# H) X5 h* p1 s! K: y& n" h8 @
速度优化问题真的很有意思啊。
# w- i/ [- E5 J! L4 Z3 ^9 @" ^; [6 e* {& b. \
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
5 ?, E# U; y$ ?' M& T& z1 o把代码贴上来看看?3 N0 o/ M, X1 ]( K- _
" l- N- Y$ E  p  h7 z
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
. t3 H8 b: M* O3 I
数值分析 发表于 2022-9-24 23:043 j2 F9 Y% [! `* G' L
拉下来?拉多少?. ]7 }8 R. N; X4 k* [2 z7 ~
把代码贴上来看看?
2 Q0 x- {8 A" Q3 Y

; X9 |$ c) b: t8 h) X; I7 @void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# ?8 i; [# \, J7 o7 [4 E{  q$ k7 i: ^* c/ ~
        comp temp, xtimesy;
- _6 g* U/ `: e$ U  @0 i        xtimesy.re = 0;. Y+ @/ u4 U6 c9 E; f7 Z+ {/ G
        xtimesy.im = 0;
! O: V- K; Q9 f1 |, @        int j0 = lenB - 1;
& i4 U2 I. D0 ^+ v        int    i, j, i1, reali;, }# P7 w# T# \2 t
        if (lenA % 2 == 1)
- w& s% C' E0 d) v' K. r$ A1 k                reali = lenA + 1;: S* }( }9 C* I) p9 v8 t4 x, \: `
        else; W' O  [4 m; c' b% V
                reali = lenA;9 F9 H+ O  ^& x& P7 n: t
        reali /= 2;" z: a4 D! f/ A8 j6 |. v" A

: |. S5 K/ u+ T8 b        int nconv = reali + lenB;
6 e" x2 v) i* d  J) ]. k" n7 C8 i1 o        //#pragma omp parallel for0 r9 E- _7 J: d3 F
        for (i = reali; i < nconv; i++)
" k: N9 n/ j3 n8 k0 y        {
, d0 Y! e% J( j5 H+ P4 U                temp.re = 0;
& S9 O) o' y0 k! h1 u' `                temp.im = 0;
" ~- [! ]: G4 q7 G$ P* C                i1 = i;
2 D1 B/ ]4 q! F3 U/ b& _                for (j = j0; j >= 0; j--), l7 o: x8 b: ^
                {" s5 y% A, I. O
                        /* floating date operation */+ M1 q0 Y  P% w
                }
2 c* V0 ]: G$ u( h& U) q
        }. A1 ]" u/ W& W3 H1 z8 B: u. |
}
. B( h1 {; Z3 C& H1 x
9 ^- e1 l" A' t' c7 W$ K6 T$ cxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
4 F4 m" }& C2 u% s) j' O0 T1 o, Y8 m# d$ \0 @0 M! ~7 n
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
% l; C1 i) s5 e; i  u" f$ d  S现在call xcorr 100次,耗时78s.
! @8 e$ p' y% L  r- S$ o2 j2 O$ z1 s+ r0 k3 ?1 r# j8 A2 k
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. , S8 x" e/ m$ w5 w0 h
0 t9 }" L% \, u" E$ Y: ?# Z

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
" _2 v; _, p( \8 }3 M; I6 zMaybe Debug mode?

: L, d4 B3 s3 G2 _  Q! s. A' k3 t! A! n7 E" ?* Z" C9 C! v+ O( S
不应该,看我上面的回复。
  l. C! s( b. D- u" H" x/ X4 P3 w" g- ]2 Z8 n
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ' Z; f5 q5 J' v& }2 e8 S
雷达 发表于 2022-9-24 23:54( \: \5 F4 r% I' o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB). \. z5 \, E- e. n( A% i
{
( R0 X, Q7 ?) h5 p/ @& o        comp temp, xtimesy;

, `6 c9 J# t7 d- [4 _( ?9 q  M2 h: i( P1 R8 d' b) A
这个不是这么比的吧。。。+ J0 b' Z+ l0 W

0 `; D4 b% U1 c+ s" a  J您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。$ a& \5 I. U& {( F, M

( W9 T: v! }, H  x. ^而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
3 k; R+ i. A% D
数值分析 发表于 2022-9-25 00:20
: V9 f$ K! h' D, z  [这个不是这么比的吧。。。
: J% B" L# o- P$ U$ m* \0 ?" r" v' I' z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

3 H% ?1 c: q. |4 m2 O8 }6 I
% ?, u+ K6 {( K: w3 M有道理。) l5 m2 f$ h9 B# b$ I/ E
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
& s7 I- L' ~/ ~' {# p. v) D5 j9 L4 P0 O! G
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
- R9 o' Z# J# e+ N0 y有道理。) M3 P* s+ {- y  I$ M# D
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

" H; ~4 D4 C! A0 `: E7 P- [你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多0 t( o$ P# c5 _; {/ Y- y% z
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:200 L4 B; H; O$ B7 ]3 n* }
这个不是这么比的吧。。。) Z9 Y2 K( z: z6 M; I

: l9 s( e2 H+ ?3 e+ Y6 m您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
0 k) a7 D: G7 _
* q. p& B; t: v1 ?7 {
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 & T8 y: K1 P' S: P+ p4 G
沉宝 发表于 2022-9-25 01:487 G# ]/ }0 a1 A/ y. a. A
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
0 @7 h4 h9 T) R& {0 V
1 ?; ?: _+ j7 a: q# r4 @" s9 x- M
是的,兄台说的对。
4 Q' D, [' P( _7 v$ r9 B% s" b3 N5 }7 l  c' |
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。5 X  K* R5 q+ ]
  c- k* A" i* q
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。1 |0 i3 W; e! ?' U6 B, ]% w3 U
& ~6 l& K) A  I# I* z
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。9 Q8 V. |1 b9 U7 E& _

0 R% e# w) n; W! u9 z/ t, ^$ {1 p当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 5 ]( b3 [1 j3 [* I8 u  o6 G
沉宝 发表于 2022-9-25 01:27
7 |, f) [/ \5 g3 Z你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
$ v1 o8 b# t1 o, u% U0 @6 B& ]
) X7 ]8 n; l9 L
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。4 L8 L% a6 C7 c; i" B
, q/ t, q- G2 k9 D& \
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47: t4 W; p( K- `" r* Y1 |  r* P' ^
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

4 H3 e; h2 ]% N! U  D8 t时间差一倍的结果可以接受。9 q+ {# t" }" _0 C6 U; P9 V" a

- J7 x" \9 i8 t你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ; |; S$ q) ?+ A2 A/ A/ K
雷达 发表于 2022-9-25 04:47# f1 K4 ]  t1 |1 D/ `0 ^
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

  L) e( O! y# g8 D$ F  }- _+ A; A2 V, o7 J
+ g( f' h" ?2 A; k6 x2 d
, o4 Z; d* E# \& O- H
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
# T. N$ x* z/ d+ o# B2 Q5 c* e; ]
数值分析 发表于 2022-9-25 14:58
. F0 ]' `/ r4 D# c/ i能不能把这个也贴上来,看看和上一个有什么不同?
/ G5 u, e  S) c; h( l% k
理了理思路,重新做了一个测试。1 f4 s& l) b" O6 `# y- N. ]/ S
做了两个 vector 和 两个 float *, 都长 100000! g" P  U5 {6 h  L5 Z* p6 W
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.( h* E, F: m' V! t% r

" m3 s* M+ |' h2 C内循环试了4种方法,
- G7 ]: @6 Q  s: o- `1. 直接调用 vector inner_product 247s
# j" N3 C6 a1 x" p7 B3 R2. vector 循环点乘累加 237s
% I, M/ o' J3 d7 H! Y3. float * 循环点乘累加 204s/ y! M0 \6 |: g! B7 k' h: r
4. 空循环 100000 次 202s
% m/ ]' m# a  O$ S- t( A
) c+ o' o2 J% I. n1 B) ?不做内循环 200s" Q' A& _; P1 Z; J2 U3 K
3 A# l: k- B8 L1 ]  c# J0 W8 J: c! O
你昨天说的对,内循环本身占比是很小的,大头在其他处理。  W( v! Q- J9 t( A9 s1 S& \
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。6 V) k4 M  V: l1 Q0 W( _! a

5 p; ^6 d+ l) l1 \7 k, v, t至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 h( M! g! G) G& r4 ?
3 y  p% v) c3 |8 T" T
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)9 p8 a8 {# I' k
7 c. ^3 J9 j) `2 `% E6 i- V
        std::vector < float > vec1(N);
0 p7 r) I$ j5 C! B8 u3 @4 a5 N! C        std::vector < float > vec2(N);: v/ F, o3 m/ I! m/ o. V
        float* b1 = new float[N];& I6 P' O6 n+ B( x
        float* b2 = new float[N];
/ X  N8 M* F. z
- |+ H& X9 M) J        for (int j = 0; j < 6000; j++)+ N  D. Z4 m) V- Q' ?
        {  E7 i$ y, F  M5 h% e* Q/ H
                std::generate(vec1.begin(), vec1.end(), []() {
: ~' D4 q6 i4 ~7 O: u5 Z5 @                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;% w, @9 ?5 `7 V1 h. B# ^7 L, W
                        });
" E! |5 K- j; p0 `; v: }% d& c6 S1 V7 h* @3 I# k
                std::generate(vec2.begin(), vec2.end(), []() {* ?. \6 R) e! a. ]- P# R
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;4 z5 E2 @4 E3 K' P# l& n
                        });
& M& d+ |, n1 j# e" r6 \+ S  c; O) _8 t, V5 A6 a
                for (size_t jj = 0; jj < vec1.size(); jj++)  S) J- m2 V6 J" b0 [' k
                {! ]* ?1 i8 J. f
                        b1[jj] = vec1[jj];6 v" u) S- U' k) s# X
                }8 {( d+ p% R8 Q! r2 |0 a9 ~6 z
6 Z$ L4 a2 Y: {$ m# V
                for (size_t jj = 0; jj < vec2.size(); jj++)
* ?9 ?6 h- |5 {, V! M8 A                {( F/ ^  n" U& L8 O4 p# r# D! A( D
                        b2[jj] = vec2[jj];
1 ~( k0 f% h1 ]$ _% R( _                }
$ L  t7 V' X' A# n9 U1 v8 a0 X" d7 A0 u, W8 J" C' v0 q
                //Method - 1  N=100000 247s  1 C. F/ ]9 s& \- M8 X+ x/ Z
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
" K3 n1 B- ?% D' W4 Q3 |1 d                                
9 C* |7 t+ V) C5 P& R" ?                //Method - 2  N=100000  237s6 a. \8 M' ]7 a. w
                /*
, W8 L; A9 D8 f) @5 F& n" {                for (int jj = 0; jj < N ; jj++)! _) U/ e- u1 y- i! L1 B0 n
                {
) ^: I6 c8 S8 p: A                        fresult += vec1[jj] * vec2[jj];
3 N# a+ R( ?% y; [; ~                }
  N) @" w! p( }, q                */
/ r. g# D* ]; `, U& G- k4 E                                1 `1 b0 E$ Q$ b" I1 W+ S
                //Method - 3  N=100000 204s: ~. r' `1 o- i4 D
                /*" F, {. G/ a+ h8 y: `
                for (int jj = 0; jj < N; jj++)
8 ~$ {. d6 x: Y! Q8 F4 b, M                {
4 Z& g9 C4 f% R0 ]$ v# `/ l" \                        fresult += b1[jj] * b2[jj];
5 ]* S( Z4 P: F% B, \4 Q                }) i9 M2 ^9 R, P9 T: A2 `
                */
% E: W1 k3 k" x7 b. `# T* c& n( n: r, L/ Z6 M
                //Method - 4   202s
( |4 }( B& O# v/ k) w7 ~                /*
5 t7 |9 s) s+ {/ E                for (int jj = 0; jj < N; jj++)
0 ?# `0 G$ \! [: d3 I7 h" \3 A                {( B. Z. E- I/ S( U# J
                        
1 A- z) h- m- Q2 C$ _- |" E/ B                }# P6 a, h( y2 z* v6 W2 y- L, [0 z: l
                */3 g8 s2 M2 i: e1 |" v
                //comment out all methods, N=100000  202s                4 H  w" H6 s1 J4 a
        }
$ Y: y2 z* w2 Q+ A& e- Z; Q6 N+ I( Z4 S# @2 A' X' s
        delete []b1;, U1 y7 o2 @7 p+ b
        delete []b2;

; p! l4 c, y- d+ _5 X* E6 v
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?8 J9 c6 D9 k5 c7 h9 p( d6 ^
" m3 W# X0 J, C+ r8 r% {6 ^+ l
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?: h  q8 h9 D4 f1 i, L' b. `

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
# S( E7 `0 n. m) N4 j1 l瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
6 B) T; E5 X/ R# k5 D0 I- |. G* Q7 Q4 i0 ?) h8 M
你第二个试验里面的j在循环里面又重新定义 ...
% P7 @4 `% K! U% d0 {( s* X# v% [
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL4 `, R" q9 S+ d6 d2 v5 b8 a

( [* k! X: D$ ]- h; O; |不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
; l1 q: l$ d# }0 X* z7 E% ]内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
, V' F! @4 @7 O
2 \, }7 |. S0 p0 S, e/ Q5 h7 Y不和它 ...
- N8 u. K, M4 q% D" X5 t- k
2 d6 _+ H$ E1 O
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
! ^# v2 ?7 _* j, g; e6 U# n, r后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54/ F# B! B+ w& E: D
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB), e4 p  m* |: D5 q; A/ O; k1 W0 S& g' B
{
, B6 _( c9 h5 Y0 V6 d        comp temp, xtimesy;

# t& G5 ?' T! b4 D; D+ y) [这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
' [9 O7 X$ ^7 Y. z' d4 I/ k内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?' ^: }6 w$ V7 t- x
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30# b: g& i( t, L4 y+ O
理了理思路,重新做了一个测试。
- s( E) F; \, j8 b3 T& `2 y! S做了两个 vector 和 两个 float *, 都长 100000
5 z( `$ ~% ^- d( m, x1 I外循环 6000,里面先做随 ...

0 r1 n8 q: [) j: u2 ~- ^这个时间是从哪里开始算的?
$ \  x( a1 l! R$ G# ?3 F) Y我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。. y9 ]' \% A1 C5 f* C
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
$ l! u! H# p* _0 h这个时间是从哪里开始算的?7 M3 w& ~8 F& `8 X, V# t9 W6 S
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

4 T; e0 |; y: N7 c我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
7 U4 R; b! s8 m2 u" ~: ], M# o你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 ]1 a, i3 {" O# z" G# U% K
与此对应用数组(指针)花了2S! W: F; T$ I7 X* O7 @8 K
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
, z9 h# f) R3 E# w2 @  Yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 R8 z, H! R% l$ {# g1 [2 ~( n
{, R7 y4 P* }% @% F
        comp temp, xtimesy;

  ]% N  |8 i1 }9 P我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
- i$ w. C% I. E& T! \7 y
) Y, f+ A& Q+ G% Z5 X* v+ J
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29+ b5 P# a8 {5 k" N/ [1 k4 D3 p, `
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
1 V; S3 T! y* v  v: v/ G+ r8 I" v0 j; l) R! a2 P# k
...

4 R9 S" P- i# p; K% M0 q* ?你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。+ l- H) ?& o- O: \9 Z) E) E: J

, O& W6 E/ M0 S7 t雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
3 {% u1 I, B# v3 E3 q5 K! R3 Z
- J# f/ t" a1 f  L是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。3 b4 O: A2 i$ |4 G% V8 Q
有空时我会试试 SIMD和并行,看看能提高多少。5 w' v. f2 Q% N, I, l/ ^. I
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 $ z3 ]7 \$ }( o6 k
谢谢大家的讨论,I learded a lot.  红包已发  
1 N0 k8 F' D1 U& f4 y  u8 p9 v4 W" U8 F0 t

, ]& k/ r8 c1 f3 m  o- i7 g$ ], L% \( [: O( {3 j; P2 Y

" P8 A6 o. \( L% [  n% W




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