爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
! T& a! a( ^7 l; n  u  e0 F/ o) _2 C# Z) k
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。# o) N* I' V1 ]! d' r2 |
3 _% X3 K4 E1 `4 K9 U( s0 D4 a
速度优化问题真的很有意思啊。* u- ^/ O; N6 r  l5 R) u8 U) `: \2 F

- [( j/ |; A9 \欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?9 N% g* W, d* D  X: O
把代码贴上来看看?9 q* l  W( }) @" L. c
; {+ Q! p" g1 c+ i. l8 T) a- [$ D9 y
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
  D  C5 M9 b& A7 Y/ [( }  E  `
数值分析 发表于 2022-9-24 23:04! V/ i2 P* B2 {$ n8 |
拉下来?拉多少?
7 J, M6 i8 x: H4 K* g把代码贴上来看看?
, [; c* U! u0 @. ]* ~: s* ^8 Y) F
6 M& ^/ g: N& z
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)  N, F2 V0 Z9 \
{- v+ N/ k) u% E# r* ]+ U$ r
        comp temp, xtimesy;" F3 L. c/ Y+ d; s, T7 u  C; ]; t5 J
        xtimesy.re = 0;
% c' o0 }* \# Q* A5 a4 j        xtimesy.im = 0;
, x) w7 B8 h( J( }        int j0 = lenB - 1;7 ^$ e3 s+ U9 y2 s. R1 g0 \
        int    i, j, i1, reali;5 E, Z8 V; b$ w
        if (lenA % 2 == 1), v8 b5 o4 v: Q7 o% P& y
                reali = lenA + 1;
& g4 v; [( Y. T! |        else
: p6 F% h! E. K; P1 e                reali = lenA;' W: {( l/ t% \0 X% f9 h
        reali /= 2;* `3 c/ i9 _7 E  H1 p- I
. {  Y4 J+ k. |0 J  ]* K: X
        int nconv = reali + lenB;3 O  Y2 o4 A7 g& t$ q: |
        //#pragma omp parallel for
2 w7 s0 i5 G# `        for (i = reali; i < nconv; i++)% e3 [! h9 S3 q
        {7 k+ J5 `1 m! j/ s& T7 Z, i! m, W/ @
                temp.re = 0;& i0 K5 d" Y+ J7 m- C3 ]
                temp.im = 0;
) p4 z2 b( z. O2 n* G6 x                i1 = i;/ g- u6 Y5 G( Y/ G4 R8 ?8 p/ i! ~% j
                for (j = j0; j >= 0; j--)
2 T0 k0 R; y; M7 S6 R                {
9 e9 c$ Z2 m/ m/ S* i4 C: \) _                        /* floating date operation */; K5 R0 ?& ?8 y- ?" I6 O5 M
                }

( W5 R" B* P  Y$ X        }
5 e& L* z5 j5 ]1 X- o0 G}/ F9 L4 X3 }/ z5 l: Y: _) i

8 W7 G* q. `7 `% dxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样- Z* ^1 _# x. o( L7 \* q
5 a; d1 c% f* P/ a9 Y0 r
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。  @( R# R0 I2 ?' i- o3 J. Y& e8 j
现在call xcorr 100次,耗时78s.: \/ @1 @- \* ~* v' f
) t3 r+ O1 Y, H+ x; ]
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
) V4 T8 i9 E4 h+ F. G" D/ C- r5 c& I% `0 v

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
% ]3 ^' \5 y  P3 l8 y8 WMaybe Debug mode?
" H! {( n; u( S( G" x% L" V3 q
3 _2 a) g+ V6 M/ k  ?4 l2 W
不应该,看我上面的回复。
1 v4 @- Z% H1 B: t- v/ n6 ]: a0 O5 b) V9 E) \/ Y2 M5 E
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
* _2 _8 s% j. i) K: S  V/ e
雷达 发表于 2022-9-24 23:54
. J. x. H5 X0 W# B! lvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- T: s9 {3 l! ~{
7 w% |. f, W5 E        comp temp, xtimesy;

4 i$ L' ]5 p# U4 y
% z& g( j- g. ~2 z这个不是这么比的吧。。。1 T8 W+ M' b  @! d4 x% ?

7 S: Q/ A2 S4 c- {0 {, @您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
: u/ V7 s+ b0 v) G0 ^
+ c5 x9 C% d/ D5 T而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
' `; F# n) w: n- _3 B0 j! `
数值分析 发表于 2022-9-25 00:205 t7 ~3 t/ G/ Z: p- e. J
这个不是这么比的吧。。。% P5 n: b* V2 ~2 U4 ?
$ i5 G9 U, z, m
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

3 l5 F8 U+ a% l) v  r: _+ ^) z# Y  X- _, }" j3 e
有道理。% C; p- K% D8 Q2 _" V
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
% `1 H7 e1 f; L1 \8 V9 y- J/ y6 q: M, l2 k+ Q, ~
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
& O# x) W& G7 A$ e# f有道理。
# P, f: L* n8 I& l所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

) v- Y  u" Z% M/ O- \8 e你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多0 s9 z/ K: D5 i& A
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20) e1 D  J+ o1 l, _
这个不是这么比的吧。。。
7 [- i: i  i/ k. x, x
5 z1 A; _6 d  Y" U( B: F3 W; o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

; K, d7 [) \; A/ D% q6 _
1 S$ J5 B  `6 O6 Z0 q* n0 l, U1 a现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
2 u! t2 N' Y3 M
沉宝 发表于 2022-9-25 01:480 L2 z  r2 Q8 n  [( h
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

1 S3 B8 G6 F* @5 F
( y* b  z3 x/ Z# ]是的,兄台说的对。
9 r, y9 v9 u0 f3 d5 F
; \1 e2 u+ |' p1 m9 n8 s其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。$ ?( q  l4 D4 k1 `  r9 F# ~
! [" p) }8 O' L5 q$ @
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
( q: K6 L% p: a' v' @5 N4 \4 Q* y# W: _# x# K1 I8 N4 _& M
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。; @  V) O5 P2 m) ]) x& L% }

8 L& Z" T" T" u8 r" X2 U当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 3 v& i3 s0 a( l' g: H: \
沉宝 发表于 2022-9-25 01:27
) |: m" U, {, I7 F  e你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
7 k1 f8 N' a! |: d' q* |
5 f7 S& J% X' s: B0 I7 ~
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
" M' l* x0 P0 _& F$ `  N$ v. m! W  R, ~/ _
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47! ?% o1 ^  m- p7 ^! e9 ]! D
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

: m; f4 b% W% H' m; m时间差一倍的结果可以接受。8 _- D$ u. C; P) X' l$ Q

' R3 m6 q4 A- ?# N7 e  I. t你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
: X7 P8 R7 ~) H" J' J# Q# x! ?8 _
雷达 发表于 2022-9-25 04:47# y  O7 C3 K: R+ w1 ^6 T4 c
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

( \- u! S: {# @' q" b! H
+ L5 z1 B/ i# `
# S+ M& t, @* J. f( X2 H; {) k2 ^8 U3 L8 F( }, [( R9 C
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
( p. g/ S* o6 U0 S% _: B, o
数值分析 发表于 2022-9-25 14:58
7 p' E& v1 e9 V; G能不能把这个也贴上来,看看和上一个有什么不同?
: O: N' y* `2 I' R. L7 ~  A' F$ l1 M
理了理思路,重新做了一个测试。  |4 k) c# I9 C. b% u) o
做了两个 vector 和 两个 float *, 都长 100000
8 Y7 B( {9 Y8 }; l4 _/ S, E3 h外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
/ K$ Q/ P2 X2 W9 G6 Z; l& S, W* p/ G" H0 S7 T
内循环试了4种方法,( [- Y  v" Y' ]4 z  w1 J( F
1. 直接调用 vector inner_product 247s ( ^; O: f) n( j2 g/ j( f
2. vector 循环点乘累加 237s" |% S  c8 z8 L
3. float * 循环点乘累加 204s
3 E5 h& x* k# v2 x4. 空循环 100000 次 202s
3 [  }2 ^7 K% z7 S9 h& ]
' e$ N0 ^( v* N+ @% b; P1 @3 Q不做内循环 200s; [7 D" p+ V* P- q. |+ o) ^

2 j0 W& ]! y5 y: Z3 I0 ^: @你昨天说的对,内循环本身占比是很小的,大头在其他处理。. D$ a5 d, i/ X: Q: J
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。4 r" O( J1 L# `0 R7 o
; P, e  E) }' A/ z+ b
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 r! G0 ]/ r" b( g' N% H( v7 `( u

) y  `- `$ a1 U5 A(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
" K. Q7 _: C! g. h8 a' f/ O
* p; E! U2 ~1 D
        std::vector < float > vec1(N);
* |) {% S/ B  r6 f& j. ]        std::vector < float > vec2(N);
" y, v& J1 u8 k5 p( U, E4 Z3 q        float* b1 = new float[N];
8 I8 I9 O) v* q; b# v  m0 j8 ^2 W        float* b2 = new float[N];6 m4 v1 ^6 x; j4 G! ?

2 C6 S' P4 f! ?/ C8 ~" ^6 g        for (int j = 0; j < 6000; j++)
; M+ k+ G, |6 T( p* W* A. _6 v        {2 @( B# X3 z7 \
                std::generate(vec1.begin(), vec1.end(), []() {4 R0 j2 @+ D8 W: ]
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;8 `. _6 C& b% w) Y
                        });1 @% J  A, X7 P; J9 |; ]' S0 N- S) a/ N
+ R: _# g+ H6 x3 i% @
                std::generate(vec2.begin(), vec2.end(), []() {2 ^+ L$ M& i( O# O5 w* N3 Y
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
/ O. r; A- V6 \, X1 P' v; j/ {                        });
! [, k4 ^- }% }5 ~& w7 P+ W) j9 P3 J1 K5 ]2 f
                for (size_t jj = 0; jj < vec1.size(); jj++)& G8 z4 x) r, y" n4 f$ s$ `" `- F
                {
1 c7 X% o; ?1 k3 q( Q. R                        b1[jj] = vec1[jj];3 \* _  v7 z& V8 ]. J. e1 D
                }
# V$ d) D5 H+ E1 k0 C+ X; O1 r  [- `$ G: F
                for (size_t jj = 0; jj < vec2.size(); jj++)% N4 n9 z8 V2 ]
                {) w/ }% ]- @" ~" G  [. N& e2 w
                        b2[jj] = vec2[jj];5 _) B6 m3 J7 Y) e1 p+ c. |1 D
                }
2 W. x* Z2 |7 U8 R; A4 u- {& ~$ m: `" y" r# B/ F2 `; g
                //Method - 1  N=100000 247s  9 b! n3 Y. n- U5 y- y* v
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);" f& G; o$ s# L7 s  k
                                
$ c2 Z4 F( Q9 y( V: K! `                //Method - 2  N=100000  237s
6 |) H7 {, X6 P8 u) ~% ?                /*& K. C8 \' u- t/ [
                for (int jj = 0; jj < N ; jj++)
" ~3 }; P4 n) g4 X                {
" b* P: U% w! J0 {  ^' Z+ t% n                        fresult += vec1[jj] * vec2[jj];' C& B0 ?  [$ b+ X3 z! l+ X
                }
0 \/ U; @- t3 ~& X                */* L& S: u& K( X6 K8 S
                                / H5 `- N+ x5 r1 {3 C; Y
                //Method - 3  N=100000 204s
9 @5 S, j2 T6 z3 m7 G+ O                /*: s9 i$ b7 n: G; @# P) p
                for (int jj = 0; jj < N; jj++)  d/ z; r2 z0 t8 k
                {  T" Z; b+ C* p% N* `- X
                        fresult += b1[jj] * b2[jj];
% o6 V; J: d+ j9 T                }
# Q: h' J' W0 p) X. j                */& k, L1 w/ Q; q8 _, y
9 p  t; `2 U! }
                //Method - 4   202s/ k7 b9 E2 i. P& i/ n5 y9 z
                /*5 g6 m- x. c0 w: S
                for (int jj = 0; jj < N; jj++)  N/ h1 ^0 A5 n* |3 `3 g( q5 C
                {' `6 U7 ]1 H6 ~- M& A2 j; m
                        
* ^$ \+ @: |' O5 G                }0 I3 a5 K8 Y$ x
                */! O. w4 W; Z8 x4 E0 ?* M  \
                //comment out all methods, N=100000  202s               
! Q+ M8 g3 Z9 _8 E, _' D7 p9 w        }/ n) h4 j" d8 M1 V+ b" \. {
9 o+ v8 A/ g: n8 }0 k
        delete []b1;% L* N. R% V) V% h" r) g
        delete []b2;
5 v: a) L8 w* Z' B

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?1 W, |3 M9 {" |; U2 V; ?

" z. L7 V' g; A  w4 G你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
* u& ^. Z1 L" g* ]4 R% N4 N7 _
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
6 \* A8 f' N0 C% `; B1 m瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
+ U" q% y2 D) C) f6 D  o# T  Z6 z7 R# W' a8 H- O5 ~
你第二个试验里面的j在循环里面又重新定义 ...

7 K* v2 B  o8 y内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL8 B  C0 A* U% s6 t3 H/ R' k

3 B2 m6 ]5 S- h2 e$ n5 @& K9 K( E( |不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:165 h7 f6 @: e* R6 X: W' s
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL: `# W( `" ~" o' e* ?% a6 i6 T
( i5 `: i5 N" Y4 g" t
不和它 ...
: N, w& K2 q  B: @- W  f5 v

5 t: }' J3 l* ]不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。9 b: H# T6 q( f4 G6 ]
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54. Y, Q2 z: ?* T8 D
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) X1 e7 q6 w  n" b
{6 y, q* ~8 \1 g
        comp temp, xtimesy;
4 ?' t% K" S* }4 U# N
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。( q  ~' X8 R! g
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?7 H/ O  t+ ~' @/ S: W- D! X6 t
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30; L. }" I' e% w/ v
理了理思路,重新做了一个测试。0 h  H% e! b1 M8 H
做了两个 vector 和 两个 float *, 都长 100000
9 B7 B* H2 ]3 G( C外循环 6000,里面先做随 ...
& r( T9 p0 Z: D' m
这个时间是从哪里开始算的?
. m2 P2 Z$ ~5 H5 M我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
# A# o9 e  \: h按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39' _4 {& N( u4 i( Y
这个时间是从哪里开始算的?
5 R; ?" b: e5 b) v" s6 X+ m- R我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

  J  W9 Z" H; i我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
9 ~& I5 R2 M' O! K/ R6 g你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。% |2 n4 D: W  m9 S
与此对应用数组(指针)花了2S5 @+ g2 W# E1 R" o% }7 v8 m/ k. J
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
& D7 g! {7 ~: b$ Yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* q/ k4 [+ H" q$ G{
" V+ k" _# J3 U+ V1 i, ?" L2 d9 U        comp temp, xtimesy;

& n  m( q4 K! _8 e7 Q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
) B3 d/ w$ g3 W4 e" A1 A1 d8 \7 ^; Q2 i; G

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:297 T" P1 K& Z+ ]9 K' W" Q
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
3 m. u4 Y# J$ \# e
2 g1 z/ K0 [- p ...

; l6 }: i. j$ O' L6 C- ~你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
3 \  i4 r$ |, n! f9 E  F6 k" N3 z
- E2 I7 o5 E4 }; @雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
( S3 H- X) R9 P
4 L4 |5 m7 s; C& q是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。" m. u" k8 a$ u- u
有空时我会试试 SIMD和并行,看看能提高多少。
9 B" k' v# k5 @9 k/ g过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ! U- a5 l1 Z; a: d3 Q% C
谢谢大家的讨论,I learded a lot.  红包已发    a; N8 ^1 Z) o/ C% y

& c7 x0 ^" v, r; p0 z2 W0 c( W+ W

- e0 S& O  ]9 H  o, q  H* m
) `2 M0 r; F! \3 [* A




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