爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?  B: t' a: b- }% C# r' V( |  ?
: Y: I' C* j. ]- R+ Y3 s) I
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
: o" V5 x. a3 u" g0 a8 e0 ^4 I' R" O
速度优化问题真的很有意思啊。
& s/ ^6 e3 t  L, @" A0 r4 T# N5 x1 z& ~9 D" S0 p
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?) f+ B8 @, ]8 \' P* e0 ~9 ^. [7 p1 d
把代码贴上来看看?
" i; B) K. D! b2 I1 k
2 s6 l8 q7 X' u  z- |; J% ]难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 4 x7 s4 i3 a/ z
数值分析 发表于 2022-9-24 23:04
1 \5 k7 ^8 o% H. z+ e* z4 C拉下来?拉多少?' y& q6 `7 I: [( d" X- [7 }6 r
把代码贴上来看看?

+ b4 Q) U# ?$ }+ S9 t7 R
9 w7 f- r# [: _2 l8 c& G, L" T* tvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)  T, \+ |! m4 Z4 J
{4 L% {! n$ h6 ~" p/ [" U# N  ]3 p
        comp temp, xtimesy;
" W& B: ^9 z5 ?4 _: M        xtimesy.re = 0;' y5 |0 ^7 A- M- l  T6 f: h! {
        xtimesy.im = 0;9 _. o" W1 V% N3 L8 u$ L
        int j0 = lenB - 1;
4 X( j* n5 |! W' s, a$ V& s/ x        int    i, j, i1, reali;; |+ V+ G( E  q: B
        if (lenA % 2 == 1)$ N' F0 F9 i' j
                reali = lenA + 1;! o2 c/ R! M& P- ]8 v
        else: z% _. |0 }7 H; }6 W+ R
                reali = lenA;
# B2 c; p4 \9 ]0 `2 M2 l        reali /= 2;
' _3 `- N' [+ t- F0 M- a
5 G# O) S' `, `, v7 F  p        int nconv = reali + lenB;
4 p, p9 `$ E3 i/ a- d! r        //#pragma omp parallel for
  y9 |/ V4 D3 M+ w% w& O8 i        for (i = reali; i < nconv; i++)% X1 ]9 K+ H3 t6 j% A6 P
        {% x' i( B9 p  [8 n/ I$ Q
                temp.re = 0;1 Y) X- i6 E$ S# N# d
                temp.im = 0;
8 R- [; ~  V* {6 E: n9 y                i1 = i;
' Q- K$ m2 N" W                for (j = j0; j >= 0; j--)4 F/ ]2 P, o: e0 N! q: Q- T5 i
                {
4 }( D- _. e: o  v5 K) ~1 F                        /* floating date operation */
; d. @( ~# @  a( g                }

9 U8 x! l& W# Z2 K        }
7 o" j7 L% b% M' j4 c$ i+ M0 H' l9 |}; k0 j  t3 T3 J  _* R+ X5 Y

; T) k6 H$ z0 Z1 ^$ E- x1 J, ?xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样( n# E% S2 b/ R7 c8 U

/ \# @' R" y' Y: q8 I红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
# V; X6 c% m( z现在call xcorr 100次,耗时78s.8 B* S) _+ o& @6 J
$ m8 |5 W3 p4 h% h4 g4 u
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 5 S+ H" M  Y2 I4 j6 S) b+ Q$ v0 s# w

% M& U* {- U7 v1 y  l
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
9 _7 R+ v  N' j9 k4 q7 H+ ZMaybe Debug mode?
) N' q* f# l# D) O- A2 ^6 y% }: n
7 I) P" M3 ?: B0 [
不应该,看我上面的回复。1 ^  [2 r, W, g$ r3 g1 c

5 S( E" e: D, V2 T* F+ S) ~8 h我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ; E+ K; [; b# T* ?7 q) [! Z4 T; z. z
雷达 发表于 2022-9-24 23:54
% H0 C5 [; \8 }* @" u6 f' fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; N; ~! A" z7 u/ H/ r% d, _{
- H6 B% F4 e9 Z& Z# g3 ^% i        comp temp, xtimesy;
/ m6 V) Z8 b9 V$ G8 U

# E; L$ ?, Y5 N  z- ~! T9 d0 _这个不是这么比的吧。。。3 f7 ]! t, j% U) V* _0 e

" j9 O9 }7 g0 t, [: l. E您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。; a9 y! `# }/ r2 ^3 A
3 d; x% ]/ U9 Y) c$ h! `# N
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 1 Y0 e; N5 d. ?
数值分析 发表于 2022-9-25 00:207 _( a% ~8 D$ G  G3 O4 i1 w0 ]
这个不是这么比的吧。。。! x3 N5 F( P3 a8 w- v  M  M7 j9 R

/ V' i4 K9 m8 z$ K9 {6 f. Y3 V. e2 P- W您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

. T! r( a" h  f$ z$ |8 t* a" ?. L9 \% g) W. Q+ {6 F/ ]
有道理。5 s# l% z7 K' I  q# ^; ]
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
$ S, \) m$ Y% ^8 Q3 g) Q8 S9 e: s5 s/ j" m
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:465 v1 ?& \+ G% H1 D! j
有道理。: D% B1 |# q3 j2 y2 c
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

5 \& U. s/ a) A' `5 l; H1 b( p6 u你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多+ o- D  }; K2 |& j
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20/ ?( c: a- a! |- `
这个不是这么比的吧。。。, v) a8 D3 \/ n$ N, l+ v

7 B6 C$ f# K& w0 _您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

% l; ^: n4 @# J* r. E9 Q. ?8 _& @/ n- T# q* j
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
1 P: l+ w6 q& [% d
沉宝 发表于 2022-9-25 01:482 T& |9 X5 T- F  e- r8 [
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
( w& K) `* }2 p3 p

- W$ ]# q0 c1 z是的,兄台说的对。% E6 \0 L* G/ `( Y

$ d$ e- K7 C5 ]& }其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
2 E: y7 B% G" g, Q0 Q% K  ]  C. ~8 q6 u" q! T# w$ S
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。/ m4 {* \( a# g1 C& {% h( q9 _

  [  H* R* X8 J/ [9 b8 e比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
8 }7 |4 M9 m# ?2 [
  J- T8 ^% _- `1 A' @0 Y: Q当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
7 i1 b# Z8 a, k; v1 w, c( e8 a. u
沉宝 发表于 2022-9-25 01:272 h; C6 E; i  @; h+ I: A
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

" T9 ?8 \7 R& I' ~# I8 Y3 G2 r; V
" e. `. f: T! v# l0 S$ x又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
$ p' A! J7 s9 e4 ?6 o' K8 _& G6 h* c+ T; u' W* B0 G" _) ]' L/ [
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47( ~  o0 X. E. \' Q$ E
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
6 r' i, e, e7 k  T) V
时间差一倍的结果可以接受。
# S" J, r2 F/ a: m' X; D1 t1 @( O, G* h. s1 L& G
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ( e2 z) W; A: L* j) Z7 H/ ~
雷达 发表于 2022-9-25 04:47
5 R) a+ Z! D$ A7 e又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

0 W' M3 r( I! p( i/ S5 ], H; Y8 a9 k
& {! C% y+ @) @6 [! v! w, N/ G) n; c, a% a

1 l2 ?" P6 x1 _: o能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
6 e; I* Q( X: H* f: G1 D
数值分析 发表于 2022-9-25 14:58& N/ p( M% [3 g# z$ d
能不能把这个也贴上来,看看和上一个有什么不同?
" @; h4 k+ J  g( [
理了理思路,重新做了一个测试。& z% T. @- T' }- X1 o) J
做了两个 vector 和 两个 float *, 都长 100000# u  Q- W4 G- u( ~0 D
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.$ a, N. k1 D" k, G0 X5 r" [
! h; t" R& r7 R) r! A  n1 C6 n
内循环试了4种方法,, u  ^' V9 A: @
1. 直接调用 vector inner_product 247s + A- B5 X. a7 u
2. vector 循环点乘累加 237s4 C* T/ B/ _' f" ~' ~
3. float * 循环点乘累加 204s
4 J2 |$ l1 {2 ]2 f7 i( a4. 空循环 100000 次 202s- L3 q, S/ a6 X! J( \

) c: K; h& {8 H& z9 y) {' G7 N( b4 n不做内循环 200s
2 Y$ F; l+ i( \- U; d' X; m" _9 X2 b$ g0 F% J9 O
你昨天说的对,内循环本身占比是很小的,大头在其他处理。7 w; ^5 \0 f, \6 }
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
$ r3 k' _  `1 D. l
' l+ w/ r& n7 X# p6 G! {至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
  B, I) C) b8 Y3 b1 I3 U/ y% M- Y; S$ P3 O4 ~  ^
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
$ E. C6 E- `* z1 L0 M
, `# r$ \) H* c, A
        std::vector < float > vec1(N);
4 V8 f9 o' n1 I3 l/ H; A        std::vector < float > vec2(N);$ L; J, x  D; ^; O. Z
        float* b1 = new float[N];
+ L) M& {2 n+ z- u" `! Z        float* b2 = new float[N];
# v) u" z! [' Q, s- p: J$ B. j' [: m/ `1 W# }4 p
        for (int j = 0; j < 6000; j++)" ~0 p' E; u* ]$ v# P! p  L
        {
1 c# E, n6 d) ]  ?                std::generate(vec1.begin(), vec1.end(), []() {5 o+ @/ z4 p9 Y7 w: O
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;# N( T  h5 B2 K7 T0 Q
                        });9 [: C- T7 |" u& H, |3 N, ?2 b

  y! j" z; h, }" O* {                std::generate(vec2.begin(), vec2.end(), []() {
* @8 j: _6 e1 v8 i                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;9 F: s. T  P% w' N8 Z# J
                        });
5 ~" g/ N; q1 r  \5 P, q; z' S' p9 w$ V  c( ^( t" t& e; j1 ~' \
                for (size_t jj = 0; jj < vec1.size(); jj++)7 C4 x2 a4 U6 r1 }1 a
                {
! U, \5 O' J6 M7 Q3 k/ R# N                        b1[jj] = vec1[jj];
6 u8 w' j$ H3 M+ v                }4 G2 g  I. {- S. P3 f& S. {

8 V% S1 r+ A% q# \3 l* L                for (size_t jj = 0; jj < vec2.size(); jj++); G4 o& h$ B' V2 W
                {% r: o. G, h# J, G8 Z$ T
                        b2[jj] = vec2[jj];) D$ C8 b# ^3 `+ d% b
                }
/ ^8 w. R+ ^& l1 _! d1 b0 ?2 V
* f  s# R# v5 ^# a' a$ R                //Method - 1  N=100000 247s  
) d! ~8 z/ t/ ?2 y- H+ {                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);* w( c  N3 H  T: r. W% w
                                
! i" a2 V, T7 z  @6 g0 ^                //Method - 2  N=100000  237s
8 N% z3 k6 B) H; b( Q! f                /*
. N9 E3 k& s$ P; h$ J                for (int jj = 0; jj < N ; jj++)$ G7 V9 P- N$ D
                {3 K0 _7 F7 o5 ^2 N) k8 B
                        fresult += vec1[jj] * vec2[jj];, N! |1 Q, j5 c2 G5 d5 ]
                }7 n- O+ z; t6 X6 ?9 z
                */* O5 W: C/ f; j( j- C
                                8 H# ~+ }, s+ T
                //Method - 3  N=100000 204s
; M3 W3 p) E5 @2 ^, Z+ F& Z+ k+ A                /*
' R5 P. [3 v) J# Y5 i7 S7 Q3 [                for (int jj = 0; jj < N; jj++)
1 J0 e1 d3 c0 H4 ^: u                {! k" y9 w. q6 c0 f
                        fresult += b1[jj] * b2[jj];
" ^$ w& C3 o, Z  t# x. C6 U; ~1 ]                }: E: ^$ v0 U/ s' v6 W
                */
- p) T  s2 D+ R  Q0 K3 e8 l) v6 x6 Y* k# ?9 q% [
                //Method - 4   202s' ^" r3 l' T5 n- q" E" X
                /*8 g* j0 }$ g9 a6 b+ T: q
                for (int jj = 0; jj < N; jj++)
- j1 w' L" }3 Z" G                {
$ J: R. I- \6 r( w1 U% n                        5 J* q) n" f. S- B3 P; Q9 E
                }
, j% e% J4 a' i7 b) l$ w% _                */% o; ?0 c) F) g* w* H5 ^
                //comment out all methods, N=100000  202s                / }2 K! L5 s9 S% S- E
        }$ T" W- k! N" K+ r$ J- y
! \% n/ N4 |: i" B% O
        delete []b1;
9 l8 {+ L/ `6 S" Z$ o9 O2 p        delete []b2;
7 _2 v* H4 }8 q! T. f

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
# J2 K: H; v: h2 Y% s; A! X( s9 A
5 x* I( k$ X9 x8 o: {0 B你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?& Q/ }  \3 x3 S3 s, d$ s) c/ ?

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
: R& Y% I5 z/ @9 c% ^- D# v瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?* o0 W/ Q/ c8 y9 Q9 N8 p
: ?6 e& t6 o) @* f& p
你第二个试验里面的j在循环里面又重新定义 ...
3 Q  f1 o2 l0 `/ W; s6 m) X0 o. A7 I
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ x. }  _2 O+ y+ X* j5 c* k

. V/ Q; M( J2 M0 f. Y$ q8 \不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
/ _/ r9 R1 Y1 w0 Z" f6 Y) [内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
# {9 j" \/ E# N( r; W0 S6 }
% |1 I" ~' Q& |3 m; b4 I% _4 ~不和它 ...
" \' L4 n6 j7 B

& J- }# T+ ?+ x0 G& |2 Y9 l不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。; J* ?1 u9 N1 @: a" \
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54) J" e  q7 v8 Q" r. u6 _0 E
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB); _1 N0 }! M! T8 m" q9 j
{: e* J8 y2 b0 n( ]' N6 w4 f
        comp temp, xtimesy;
3 j2 ]4 [# |3 ]1 b1 R
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。6 C2 \3 H. w: K0 v- C! W
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?* S, @3 K5 u/ k7 G: B: [0 `6 @. T
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30+ J% X* ]3 q8 c( q. J
理了理思路,重新做了一个测试。
, m$ \& u: _* c8 D2 m7 l% b! m+ _做了两个 vector 和 两个 float *, 都长 100000' q% Q2 j+ ^) F6 H
外循环 6000,里面先做随 ...
5 T1 P- U1 j0 n( O8 @. }$ f
这个时间是从哪里开始算的?) W5 I; G8 f% l" G
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
5 f9 Y* O; O/ b+ ~  d0 u$ P9 S- o) u按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39! f! F! g5 x( ~0 s
这个时间是从哪里开始算的?$ V% L* D/ b% k: A
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& V7 ?. @  _+ e8 l  E
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
' y7 ~$ e% N) p2 a; X7 a你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
) I6 q( ^+ G. S, z  ]/ _; B* }与此对应用数组(指针)花了2S
% W% A7 P0 X; M. ]7 Q2 J. t你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
9 v7 n9 f2 `! p* Y! |0 Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
2 a; j5 G2 s& O6 j4 [- e{
: l8 s% p+ O7 Q* i0 n( F        comp temp, xtimesy;
- S( v; w. B# ?8 k2 s+ ?
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗/ u' k* ~2 d  Y. F4 w

7 K6 {. U' h/ p- O1 L; Z
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:298 i, Z2 D! A  q9 y
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗* s% z& B  n* W% z

4 B& ?  v* r0 c5 h ...
. N7 K: s* k, G8 g- z" q0 @
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
9 o! x/ o7 j2 M4 x2 A# H, e# Q- j+ \. Y9 v$ S
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 1 O5 U: H. a" b6 ^, V; M
7 q8 r* Q9 _' k
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
1 S4 f" J/ H, W& ^% i0 k/ y$ U7 e有空时我会试试 SIMD和并行,看看能提高多少。
+ P% W) n0 G' S, V过去7、8 年没有正经用C++ 写过东西,没有 sense 了 9 H0 V, q2 Y3 X+ F& ^
谢谢大家的讨论,I learded a lot.  红包已发  5 t5 @1 n8 [+ D

) N4 j% n' P& N' a  ~, z0 f
  Y" S! f$ a) z4 r3 T4 b/ t; v' _0 i( I, g
) W( r1 i/ l; y8 }- U, N0 _





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