爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
  G. d  q5 ^" A( t! q9 E
/ a/ G, @7 }0 n/ C/ z3 N自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
8 b6 T2 I& w9 w$ q0 I5 ?, j
3 r; D* H) q9 D+ I" W速度优化问题真的很有意思啊。1 V& n7 s" @- x& C& G, \! i

( d; w8 U0 l& w1 N0 s; J欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
7 l7 S( E$ `" m( c  h# a8 t6 R; }把代码贴上来看看?/ J6 S! L$ v8 j# h3 p" O3 g

5 a" w: o8 b5 w4 C0 m难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
. H. D0 \9 ]5 n7 Z
数值分析 发表于 2022-9-24 23:04, K( b) t" {1 ?- o3 n
拉下来?拉多少?# z) ~0 u* R. ^% f' w1 C
把代码贴上来看看?

7 j% Y9 g( U5 C" M* p5 G& b) A; g
2 A0 z6 t* t, h+ M* x* l9 O. ovoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) w1 k7 U; H( {, I; s, C
{. X- \% b. d) o
        comp temp, xtimesy;
  q( x4 ?  c2 W* z/ C1 X        xtimesy.re = 0;6 n3 C; \2 r1 p
        xtimesy.im = 0;
! V4 s7 Q3 D# i+ {6 P0 B        int j0 = lenB - 1;- T( Y, [3 I  P( b
        int    i, j, i1, reali;
5 c1 x! d" y; |* h/ g! @2 @8 j) k        if (lenA % 2 == 1)" ~1 @+ j- p% i3 k. g9 Y: |# g
                reali = lenA + 1;- Y4 \  e, N% n# D: ^" V
        else* f7 @6 `" P6 Q# k2 h* e
                reali = lenA;
* N3 m( ?! E  u' ^* Q$ ]2 I) E        reali /= 2;
5 `6 @- V3 s% i$ O6 J! S. l2 }1 ]& O+ p
        int nconv = reali + lenB;1 Y  i5 _( q2 G3 z0 Q; {" J
        //#pragma omp parallel for  ]# Y4 M0 @! Q
        for (i = reali; i < nconv; i++)
9 j+ Q: M" s3 r9 l0 h. ^6 o+ \        {
- B, m! K! v& \' i                temp.re = 0;4 L% n0 |9 ^1 t6 F7 }( K
                temp.im = 0;1 q: A0 y% U* P, L) l
                i1 = i;* g3 s8 _  J( q7 n: B7 H! B4 Q
                for (j = j0; j >= 0; j--). Q: j  |# D) \# }4 M7 M* b% k
                {
& ]8 S; R* ?. s4 N" r% x2 W- D                        /* floating date operation */2 M) t* A& G* f9 A0 l1 G
                }
: _0 N; x& y5 ]0 G0 D
        }
3 h+ X0 s: F! o- F' U}
8 T7 F2 H3 y! B2 }* f% j3 v3 n5 u2 m# u% f* n5 I
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
% e7 e* O( m6 z1 K/ t& N$ C& @1 W  X7 h5 C$ t# e+ |6 c
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。+ t7 H' h1 z# j/ k% r
现在call xcorr 100次,耗时78s.9 R+ n5 m  h5 U& ~6 j

: y6 L+ A* A5 f2 M0 E* _3 \如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
& T! F1 Z0 h/ a9 l* |
( W6 y' t0 O; Z# P9 K5 R; K
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33# B  u- f% S3 }3 D
Maybe Debug mode?

3 n. L! m; W  Z1 w
# J, x1 n0 x! d不应该,看我上面的回复。
+ c. _) b+ o1 F0 |& r+ i( U" Q- [, |6 ?! l- ?/ R
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ' y. w5 S& ~/ ]% i& I. Z, i3 H$ ]
雷达 发表于 2022-9-24 23:54/ [' k" L( ]$ D, r# G% C' V9 q
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* O  s; Z/ y+ Q) ]/ l: w2 V{
1 _1 w6 m8 |( s2 ^        comp temp, xtimesy;
2 g- @0 O3 ^+ @& u5 w: o
0 U0 [6 m0 {" J% Y* b4 a* Q
这个不是这么比的吧。。。
* O0 g$ v5 c$ p" t
! a9 Q5 R( S1 p6 s3 \7 g) Y您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
4 v& Z2 Z, c/ Y& k6 ^, Y& W- j) g% r6 ?* E( W1 K
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
- G+ U: T* c, K& e! f. S
数值分析 发表于 2022-9-25 00:20
: B1 o0 F1 n: s' A2 m这个不是这么比的吧。。。
9 K( Q7 h3 Y# x7 h( t) k4 n3 O
# p/ j$ Z, B0 z+ o0 S$ D0 B您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
% z6 T$ z6 D9 K& T

' H/ @7 Z6 ~* ]3 r! c有道理。7 r* j* Q- v( I8 {8 A; n9 k
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。% d# y3 Y; M) s4 ~
, F  y; `6 g1 m' F" z  t
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:461 n9 h$ q3 _* Y$ r# U
有道理。# R( T1 J2 j) ^  V; f4 D
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

7 J. {+ w. p! M4 C你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多* o4 g) s' A8 f; J
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20$ M0 y! F$ o, j# f1 Z) v9 h3 V
这个不是这么比的吧。。。
, S9 L  ?1 j* t! c8 v2 c, c0 e6 V4 }$ x
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

* R, j: _4 d( C( X/ C( t* H* L4 c& V3 S7 D/ ^
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
- p4 o/ Z$ ?8 _
沉宝 发表于 2022-9-25 01:48
6 K4 G! |+ a9 c4 Y3 `' e" Y% W现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
- S  F) X+ V' l+ x3 k$ |5 J

/ W2 q7 h7 ^+ i! K* P. W是的,兄台说的对。/ ?2 _5 T  A! o+ o

  D- G! T/ k1 s9 }其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。. ~6 D+ h' I& E5 \

6 @0 v4 {" y' y# p& D/ i4 V  U! E; ~雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
8 z0 t; m% L0 {. [- d; o9 F
# l- R8 q6 M- B$ o比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
) M9 [8 f9 Z0 \
. z0 \3 k( F4 I# r当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ! N8 w. u, F1 W$ E0 y; _* h: W) l
沉宝 发表于 2022-9-25 01:27' R$ p8 D* s, m9 R
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
9 S9 z% S, [, ?9 N: l% T1 k9 _+ {& f

" B  v) C2 M" S6 W又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
3 L8 u" T" P3 G6 q8 P8 r, i) G. h6 \9 e
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47% a2 j# x% |% T
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

$ Z: B/ V2 Y. S* G" O时间差一倍的结果可以接受。: y! m8 [( y7 z& C

. ~5 K4 b8 S1 h9 m你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
7 B& e+ u) p! ^9 I! T+ O/ C$ Y% f
雷达 发表于 2022-9-25 04:47. `, u0 a+ y. a; y* n
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
  k3 D  a2 y# O& _

$ E# m% h) J( ?5 [8 j5 R5 a' O( V( Q( t
& G8 K5 `4 f( K! j
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ' U* G4 C2 h9 C  }+ _8 w( y3 H* F
数值分析 发表于 2022-9-25 14:58
# j) a6 I, p. ^* y& C能不能把这个也贴上来,看看和上一个有什么不同?

5 y- S8 X, ~+ k4 K7 p) ~+ ~理了理思路,重新做了一个测试。2 @9 I2 `; A/ }) o+ g% c7 ]
做了两个 vector 和 两个 float *, 都长 100000& f; e* {$ \, H# L6 X7 N) K
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
# G) I3 ^  p( M' Q: m3 h: H0 U6 d2 y8 }1 B3 r  W
内循环试了4种方法,
1 T# N9 V' B/ W# }' Q. w1. 直接调用 vector inner_product 247s 5 t8 j5 _$ f) A9 M9 v* L  v
2. vector 循环点乘累加 237s
4 r9 s2 G& B9 F3. float * 循环点乘累加 204s
3 ~! g1 m/ b- n6 e4 x4. 空循环 100000 次 202s
0 y% T- }" k' L* F
4 m$ N8 m0 t2 j) c! B不做内循环 200s
+ H/ s1 [* {+ v3 Q' [3 `% g, R8 l; G+ ?9 r7 a
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
- m% Y3 L+ f7 }/ q1 J7 F6 P! i另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。+ D$ S  L+ b7 t  P/ O

$ k% d1 _3 T3 F* a* E至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% {+ ^6 t  @8 H1 m1 V+ |$ b
  Y6 a  B' a3 W$ |% w; f0 e
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
9 X+ T9 o) \/ g; d) U/ k2 s- K2 q  \+ C
        std::vector < float > vec1(N);6 b; d0 X; m6 |
        std::vector < float > vec2(N);
* G% ?' ?8 C+ l4 a' T        float* b1 = new float[N];* Y8 L* a7 K  c" H
        float* b2 = new float[N];' _( r# t8 R9 x

1 }% A( j$ C0 J! A$ Y" V        for (int j = 0; j < 6000; j++)
: y; G( F& N* L        {
' U6 Z$ ^, E5 @                std::generate(vec1.begin(), vec1.end(), []() {6 I  M" g6 x4 v" o) {0 _; H' E
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;+ {3 C; P! @/ @2 T' n" o
                        });
& r# W# t$ ^4 _% d: R
7 C8 J/ ^% L+ F. E6 p) I8 I                std::generate(vec2.begin(), vec2.end(), []() {* E) Y- C' i  M3 A6 I" u
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
' r0 d) M+ B0 o0 x                        });
% `7 L$ {( r2 b5 o5 Z5 D( {
. I: I4 W; a' r/ L2 }: S                for (size_t jj = 0; jj < vec1.size(); jj++)1 m# O( j/ d, x0 v8 x
                {; O$ Z* b. H2 d2 Y8 R
                        b1[jj] = vec1[jj];3 \+ D0 Q8 S* q  ^- N
                }) V) T7 Y9 E( c3 e# D$ s" E6 `
& N: l4 T! G( T# m
                for (size_t jj = 0; jj < vec2.size(); jj++)
0 h9 d$ \$ u8 e" q                {
; h4 y0 A. @# p# g1 [& e0 `                        b2[jj] = vec2[jj];
; c- h4 y1 w1 v: Y! ~( A                }
. Y8 x; ?5 v& \9 S' F
% L% X5 w: P# V. w& q8 H' s( d1 G                //Method - 1  N=100000 247s  
) l1 s% K2 J3 L! R9 O                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);, q0 @+ P5 R# S5 f7 O
                                
; R3 Z2 M; t9 ^6 T7 }                //Method - 2  N=100000  237s
3 C, Q" d' q4 y+ X$ [* t4 _                /*0 [- {% y, ~' ?: `
                for (int jj = 0; jj < N ; jj++)
- E" C' o/ t, M2 ~; c                {9 M2 k& t9 g7 P% w5 M8 m
                        fresult += vec1[jj] * vec2[jj];5 E/ z" g* }% l1 g! t  b9 b0 O
                }4 r5 N, [. I4 c4 Y# N+ T8 p
                */
+ ~1 q4 l" i0 u% c9 r9 D+ `                                
, [0 Z2 x7 e: {' m, C                //Method - 3  N=100000 204s
: H( Z7 _, |7 ]% |                /*
/ H$ _# n& c7 f/ q8 f3 m! Z                for (int jj = 0; jj < N; jj++)# u+ Y% v. i9 E7 S# ~2 Q) S
                {( g( A! x( F) G+ e" ^
                        fresult += b1[jj] * b2[jj];: |- T; T5 u2 k' |+ r4 y7 c0 n
                }+ H+ V/ ]. E" i. R3 o
                */" r  I7 [' C/ c! g
7 g( i0 b8 f- z. c4 k
                //Method - 4   202s  `  X: Y. a5 l* o+ ]# U- I0 W: a
                /*
2 i- D  q/ p, e( q& ]7 n( i) x                for (int jj = 0; jj < N; jj++)
, p- B2 a1 K) V/ w" g& n- y                {
  Z  U5 z& c7 L- r                        
3 v8 _) W7 E) w* e                }0 C0 `$ T7 ^, _  G
                */
' e, N0 f0 J: S5 Y8 U4 k                //comment out all methods, N=100000  202s                5 H; H3 X- A$ a5 p' `0 E, f% ?5 w
        }4 L# U( W- |# e
) T# i4 {( p% F8 M
        delete []b1;. ]( b5 L/ e$ ?* z7 h, o  @; y, ]
        delete []b2;

9 V* y6 Z3 N  _
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?: h( }8 N9 ?7 R0 o
  g/ n7 ?, L# P2 a$ R* I% {
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
/ x: G" m) [) V
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15# _, L+ w& L) ?; n
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
* E8 r4 K5 A3 B' O2 g
; \# M& S( D. ]7 k+ F4 n你第二个试验里面的j在循环里面又重新定义 ...

2 [: o6 ^8 D  T% g$ D: w内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
. o# q; Z1 G4 |8 _0 w8 N4 M
8 v3 G7 w" ~9 @! p8 h& }/ K不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
5 C; o/ C9 J; d8 n5 n2 E内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL2 _  E( z4 B- B% `; [

  r( C5 o8 k5 J' J! ~0 X. M不和它 ...

. r7 Q# K8 G/ E) d2 E4 ]6 f/ l+ R0 u. ]' x6 l+ ?+ h; j
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
1 x, \' s2 y' Q8 j6 ^( c. |9 i后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54( l3 p& S2 l$ X9 D7 b' N1 O5 F+ G
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
% u, J- @$ \/ E( F{+ u; ^  A, n+ R" B/ j
        comp temp, xtimesy;
9 ^9 t" S1 v# c' k; K! B8 s# l
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。8 i& r' L3 b. X2 U
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?3 Y- f: }7 s1 i+ `+ \& i3 w: G: b5 Q
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
$ f* e6 v; y' V7 X% v理了理思路,重新做了一个测试。
7 b  G" a% i2 s$ x% P做了两个 vector 和 两个 float *, 都长 1000009 j) G3 Q/ Z( t/ \  w, a
外循环 6000,里面先做随 ...

9 |5 l8 P& x% Z3 M* g5 U这个时间是从哪里开始算的?
- s  R. w" C0 h, Z2 O" x, i7 {$ o我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。* F# ]+ Z5 M3 C, F. S6 C
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39& H, G3 ]" D1 c" m% b
这个时间是从哪里开始算的?
/ K* J. Y9 f! e我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
: n6 [7 Y  l, m( }6 V. o7 M
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。, _1 p9 s. M+ z" j
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。# [# j- v0 n1 o! R8 ]
与此对应用数组(指针)花了2S0 F" y' `( p2 w# S9 V5 t4 P0 t0 v
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
$ P3 j# g; |) l- X( Jvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) Z1 C5 @( `7 f0 ]+ Z$ P( w
{6 W, ~5 d( H2 h+ P+ D
        comp temp, xtimesy;
' q# r/ s# E; ^5 p
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
# R' t9 W5 |) U0 c. m. d# l3 H+ v6 d- N

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
5 K, y0 @: @4 w. U# N我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
" {  M' n7 `8 d! m% ~& _' C' t
: P0 u1 r& a/ s" @" V ...

4 n3 T2 Z2 @+ }$ t, H2 S; a你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
7 [7 C. {$ t# }: \/ `- V4 |: y; M" ?
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
0 J, c* ^4 x; }0 j% P3 O' N, O9 Q7 L
, f. W! H6 s3 @4 z7 j' V) @是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。2 g7 h. W' ^* @+ c
有空时我会试试 SIMD和并行,看看能提高多少。- [2 l$ }$ e3 P- {
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
! q) Z. l4 E* e. }3 O1 G1 P谢谢大家的讨论,I learded a lot.  红包已发  9 _- {/ v# q3 X! {3 l
$ n% P! p* s0 S

) Z4 `" b' p$ ^7 ?0 o  }7 Z2 l7 {
6 G; S, E5 X0 h3 z0 M7 ?- W+ s; m0 q





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