爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?  |3 z; X% R+ |* G) c2 x# F9 U
" ]/ L, d, P, M$ E
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
2 K/ V- t# f+ f4 n2 T, s0 i& e7 E5 }- X& W7 j" C
速度优化问题真的很有意思啊。
( |6 [' w! U7 B7 R0 j' M% F/ f" P8 `8 K
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?- i7 G8 D4 ]8 r8 j* f
把代码贴上来看看?8 h5 c$ O; |" l( u" o8 z/ V

6 m4 x3 O2 t" v难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 1 \3 J5 r. w6 P6 l% F7 Q0 v
数值分析 发表于 2022-9-24 23:047 x, ]( w* G) ?# H/ I
拉下来?拉多少?
6 d: G9 w' A+ j9 F3 B2 f: }) \8 z把代码贴上来看看?

0 ?6 ]1 g. ^' F- w. M) w
+ I# Y1 Y9 p4 M1 J9 S0 Nvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB). x, U6 P% R( X- X8 r: a
{
7 \$ O, ]- f6 C6 P: a6 _, M& p' B$ L        comp temp, xtimesy;5 X$ c! U7 U( s0 B
        xtimesy.re = 0;! l2 X9 [9 ]& R, x+ n% |1 n
        xtimesy.im = 0;' [. x5 i+ L; M0 j/ K( B
        int j0 = lenB - 1;; x, @. `9 V2 G% a. m  Q
        int    i, j, i1, reali;+ A' g" p4 _' X( }
        if (lenA % 2 == 1)
$ l& V/ n, G. ]8 I                reali = lenA + 1;
3 }( J- T' T& f% }" x. f        else
) |& \( \3 v2 s9 R/ O" W, S( w. J                reali = lenA;1 r5 C  [  a+ G# g2 l. J3 K$ B: c0 p
        reali /= 2;
4 r2 m/ t" O% _2 s" j2 G' T
* _; A% n- p2 z- g! k1 k' Z        int nconv = reali + lenB;! G9 x! \( B# r, S/ E: W! v
        //#pragma omp parallel for
; T# ]5 z8 u3 V  \4 b        for (i = reali; i < nconv; i++)2 Q/ [; ~& ?8 `" ]4 d
        {$ V1 S  I& p9 F. B# Z9 B
                temp.re = 0;
) `. y, k, G3 T) x) f+ J% _                temp.im = 0;( i6 u* ~3 s% `9 J% _0 ~/ K
                i1 = i;! x9 S2 t7 |# D& }
                for (j = j0; j >= 0; j--); J9 a( G2 {) d7 f
                {; G2 ~, d& O/ A' I0 Y, C
                        /* floating date operation */) @6 Q, A: x& T: W# S. a
                }

3 Z2 i. I5 V) r2 k) F- E        }
# }; W# @% [% v% _% u- G}$ N; l% ?( `* J6 n5 Z4 L( I
2 n0 E9 `2 \7 p. e0 C/ Q
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样: |* @3 ?# g* E& l

& q  j4 C) ^2 u红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。% A5 o! Y9 ]0 K: J, w1 c
现在call xcorr 100次,耗时78s.- p1 v  A& o; m2 o8 T: m

/ S* d( P7 q7 F! ~0 U如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
6 \# k7 T+ W$ m" v3 \- H) f  ?
6 D* i! a% q# `* @
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33& B# v5 s. [: V1 t& Q0 N
Maybe Debug mode?
1 ?7 e, o9 t8 x, M2 ~  y: Z( v% c
3 d4 A7 _. N) k3 q- j1 t
不应该,看我上面的回复。) N/ T/ U4 Y4 M/ ^" Y9 L
4 z0 l7 V# {/ I* W' P- E. s
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 9 u( f: g5 y! C; p
雷达 发表于 2022-9-24 23:54; S. T5 t% @' J+ \, n( q) {& m
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
& W0 J; @# B) x5 H$ K6 o' g{) U, t$ v: g- k; s" Y3 {! L0 k
        comp temp, xtimesy;
6 r1 g1 V4 _% [! _- g, t
& s" O0 M3 o4 C8 J
这个不是这么比的吧。。。# l0 z) w# K2 U2 z* [! W" M9 J
# k( C2 ]/ P; }+ q1 x# F0 }
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。9 N' b9 @4 ~# `+ r  V2 F

& {' H4 w- V# L2 ]  \: r0 `. B, Y而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 / C7 @* B/ ~- p4 Y! [+ k$ }
数值分析 发表于 2022-9-25 00:20" s' t6 h& v+ Y9 M
这个不是这么比的吧。。。; J! L3 F+ M- ^7 `# m$ B: J

9 ?$ |+ n; O2 _% {7 Y/ [( s您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

' s1 M' F& l; |* x5 H: ~! r% X1 x; w
有道理。  `# k% k% c0 I# ?. ~
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
! G$ d# Y/ o5 q. u4 x# ]0 I5 `7 I* B* U# c4 g
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
1 x1 ]1 i, ~; M, ]2 N' I  G有道理。
2 F0 ~& B, H, l! A6 \- s& D0 [所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

$ _) O. ~0 v# B: f你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多" b0 o+ Q2 b4 N4 K9 u
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20/ @' ~; X3 ?1 E# W+ G
这个不是这么比的吧。。。
6 ?" I/ z& U# N- p( J& l9 Q- l$ _' s4 g% w, q0 ]" r  K' u
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

4 U" v7 {$ e7 r8 e7 ^
/ A# `+ r' m% n0 a8 }. C1 A9 j现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 0 f& f$ A) x# b. b
沉宝 发表于 2022-9-25 01:48
4 G: n) p! U2 o/ I, u5 o0 c- r- J现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

, K8 f9 G( R% c' U& q" r# V$ q5 S" x% C
是的,兄台说的对。7 J  k7 y0 p2 z/ u) B% f8 g
$ d) S; J* Q. t3 T  Y
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。* i/ r# b6 l$ q7 w- S- _  M0 Y0 h
/ `- ^* Q6 G5 N2 u+ Z# G
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。( H% g$ ]: M/ J9 I9 y' U) H, S

* A# b6 T1 n  t) ]  X比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
+ \! W6 _* f) i1 }
! f! d4 t7 W2 |. {( s0 ]# n当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ! |/ q9 O+ x' k" n4 C
沉宝 发表于 2022-9-25 01:27! I' B3 k3 [$ W& K' e) r. U) y
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
8 H0 y5 }( ~3 b$ ^

& S# |0 Y  V; [& ], |9 p% E" q又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
& l3 z! K2 N' U1 C+ W7 i, r' }
+ _% `. o" D! P我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
9 @/ w# {6 O% G$ L- g, A1 H又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
# c" X+ O5 A* Y7 }0 u5 A
时间差一倍的结果可以接受。
* L0 Q9 T, W& [/ ~! Q( @0 g/ R$ s% \7 ~  t7 }2 R
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
( O4 J5 ?: {7 b. G
雷达 发表于 2022-9-25 04:478 s, J1 ?. \8 W
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
1 Z" `" h: Q6 q, I% L0 o

6 f. \# O6 L8 `( `! t3 T* m2 x
5 [9 P5 j6 v5 `% T3 P1 @5 [* y) E  ~0 a. ?' k7 P8 O; `& h
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 8 u' Y% |9 n7 O4 D+ }
数值分析 发表于 2022-9-25 14:58
. w( G: x! q0 D7 I. |3 M" @" J' S能不能把这个也贴上来,看看和上一个有什么不同?
9 c0 `) O; t( K5 d. Z. n
理了理思路,重新做了一个测试。
, N) Y4 d# \$ G+ k3 Z  x8 l做了两个 vector 和 两个 float *, 都长 100000
5 {7 V1 _, r) o1 c外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
7 m; u  A* X! B1 p0 F
) Z$ q: }2 U; @0 t; C内循环试了4种方法,! M! w6 _/ b' O# M& ~9 I
1. 直接调用 vector inner_product 247s
/ o6 n& ?% S& Q* t2. vector 循环点乘累加 237s* A3 e# q2 K7 i% J& \, F0 }
3. float * 循环点乘累加 204s1 q8 l: O/ B9 w7 f$ r' n+ a
4. 空循环 100000 次 202s8 B0 a7 U/ _  F) z, J% U

2 I/ ]9 K, _% n; m2 Q: S% [不做内循环 200s
) Y& L" i- N1 q$ C6 |5 H# \! Q+ f# }8 p
你昨天说的对,内循环本身占比是很小的,大头在其他处理。( o4 a# q& f" M6 v# [% y$ Q
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
' W. b; ~/ d+ u' P" f# r: [% [% B  m* G* u! o; W* U
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
! ^: E, U) B% n& A. B: I3 F
/ e( e( }$ w" @(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)1 q& l5 g% Y) O8 W, l2 V
8 k+ Q: G3 Q% {% \0 q3 p- C
        std::vector < float > vec1(N);
- r9 s0 E! ~3 F. N8 }, C        std::vector < float > vec2(N);/ l3 h+ R+ @0 P- [8 v
        float* b1 = new float[N];1 m% f% p) i! j* J/ a# c! |
        float* b2 = new float[N];
1 [! \- x6 r( n  L- V+ @
5 _1 ], c' C- K, R7 r5 t5 ^0 N        for (int j = 0; j < 6000; j++)9 H  \8 P4 g, S$ Z
        {
% z4 {  S( L; Q" l( m                std::generate(vec1.begin(), vec1.end(), []() {& j) t4 U/ X8 f0 V* \1 u
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
) ]4 b: ?0 K8 J; ^                        });+ D4 a; L2 v8 v! i

: Q  Z1 M' i3 j7 a$ g                std::generate(vec2.begin(), vec2.end(), []() {
5 q/ U2 |1 `; a; U- Q) e, S                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
5 E" L" @4 _& W1 ~3 N4 X) ]: P                        });
; B, Y+ E! a/ b# t3 b* N! L* o6 d7 T/ z# u0 E2 Y
                for (size_t jj = 0; jj < vec1.size(); jj++)
8 e$ M6 D0 ~" O3 e, a                {
6 R) u# [- c- H( T                        b1[jj] = vec1[jj];
7 u$ ?* E" }& I& D: {                }+ X1 {4 A8 J+ `

; }% O( I5 P( {                for (size_t jj = 0; jj < vec2.size(); jj++)
) b2 ?3 e' [6 F" p1 v$ A' Y                {
1 S8 D9 a1 I4 X/ t* l$ B3 {& ^                        b2[jj] = vec2[jj];/ }( B& y' C& C7 y$ e& |/ j
                }
1 D7 g- T0 l6 @. d: A: I3 f" Q+ ?+ @9 J7 l0 W. w
                //Method - 1  N=100000 247s  
( }* L4 N( n4 W* i9 O1 {                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
, X$ F3 U, E, C# B( _9 z' ?                                
7 X) @% d4 _4 a4 d. i# Q- s/ @  v/ z                //Method - 2  N=100000  237s5 O# ]( z: b* M7 Y; e5 A
                /*! E! N# q- `0 g! F6 \9 o- A6 I
                for (int jj = 0; jj < N ; jj++): x. O1 g) ^% H3 b5 C1 g
                {
  b, K7 [" v5 g4 q  U, S2 b$ y                        fresult += vec1[jj] * vec2[jj];
) u. a5 x9 F% p8 ?. J9 ?/ P                }+ o+ s/ e% Y  p/ ?
                *// ~2 j4 x1 m  j
                                
1 \( J9 M* N0 g: a# @3 B% m8 }$ h4 k                //Method - 3  N=100000 204s
  a/ o- w9 Z. C" C                /*, B; Y. Z  ^( Z" Y4 V
                for (int jj = 0; jj < N; jj++)
$ {. Q# Y* Q" Z: p% n3 W: M  T7 ^                {
: A( [0 d, r# I$ Z& m' r+ J                        fresult += b1[jj] * b2[jj];3 f) Z0 X# J1 J3 d+ d
                }3 e. R8 c4 N& Z; J0 ~
                */( k6 T% a: l# {
% c" m5 U" m. T2 p* H5 _
                //Method - 4   202s
+ d4 P& L; p" j% Z! G                /*3 i: M+ L$ P2 }$ h
                for (int jj = 0; jj < N; jj++)$ q; w1 e8 R5 {) ]: Y
                {
: r' d) @- a" p8 ?3 \! P! Q                        3 L8 O7 @6 E' m6 z3 E6 F3 {: f; v! r
                }/ v, a% S& s8 L! @
                */' Y; m4 P6 e2 t, n
                //comment out all methods, N=100000  202s               
5 Q5 t; C* D# w6 U& f        }# P0 t! Y, E9 A# |4 g1 z
. K: Z. @5 y+ O8 {8 N
        delete []b1;7 F  |1 U5 V+ n
        delete []b2;
% h- f0 z1 u. z! s0 h

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?; s. V, n. l! w* q& r# g

" U6 c1 O- G: I' E$ m2 k( n你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?/ R% P& ?  x" h# G" a

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
8 h; A) Q, E1 n; ^$ V瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
8 ?1 U! M' e0 {. g1 O( V! ]: c$ H  G# w" s! g
你第二个试验里面的j在循环里面又重新定义 ...
7 |3 A; j  E7 _( D! u, y
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL5 g# Q# z, I# }6 p( f/ @
7 J6 d& C2 U) w* t* X
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
) E( N  h% s* V: B  f8 K8 I内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
' r( F  Y) \! ]+ u' w7 A( k
. ?9 x, U8 ?; `8 M- D不和它 ...

0 r' G  h3 S" {; a
# U' z4 J8 J5 Y0 O不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
: ], }( W7 O- ^0 F% q7 Y后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
; Q. v: Q$ _/ e) a* uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 p5 ^7 x5 b: O. h
{
, c7 k9 h7 `5 r6 q4 G; ]        comp temp, xtimesy;
* q' r! A9 I" G# }5 F
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
: `- H6 u; r: n; g" R( L' T内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?3 n% X, x6 z6 J: K2 o: k
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:306 q5 h: y' ]& C( `3 N* e
理了理思路,重新做了一个测试。4 T2 @, J; T  s; Y) Z5 L4 o# ]
做了两个 vector 和 两个 float *, 都长 100000
: T+ R' k& C) f* j. o; c外循环 6000,里面先做随 ...

) w+ K6 B8 `6 k) P" r2 u这个时间是从哪里开始算的?
3 Y$ C, L+ _8 y+ R) q我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。5 g8 \* M, C1 p, W
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
% m, v4 D2 |. G' q4 y这个时间是从哪里开始算的?& `- S. o8 H! P' I
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
: Y: R9 t1 ~4 A. j6 z/ r3 n% v
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。  e: f4 X/ d! }/ ~3 a
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
6 {3 [4 v$ ^6 M" B5 f与此对应用数组(指针)花了2S+ `9 N( R# h, O" W- z
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
* F2 Z) H, j. Z6 ?4 Nvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB). u* n( ?  G8 f; O1 U
{5 T8 e$ J: f$ n0 B# z& c
        comp temp, xtimesy;
- i" O, p3 V( Z* C0 w. h+ a
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗4 P( z8 X. c9 L6 q  y2 z

' O, ]8 o" Y) S* S$ U; ]- v
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29+ _- `7 V. f% c9 \6 G
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗1 h! j. p/ V2 t. h! N

6 k; y/ C9 o  _( s9 I% C ...
5 _  t! e: ?9 I6 x& s# X' G9 R
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
* v5 L+ o4 X* Z% U% M4 K. U! _; |4 k8 ?( }
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
& a* u' V2 \3 O* W( N5 d
9 L5 _& m# r" I, M% }是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
% P# ]2 Q. u" d, s+ Z有空时我会试试 SIMD和并行,看看能提高多少。
: Z! W) m& i6 X5 a/ V过去7、8 年没有正经用C++ 写过东西,没有 sense 了 0 t3 Y+ c2 z1 t/ E4 M: q
谢谢大家的讨论,I learded a lot.  红包已发  
, e% o) y9 ]- J8 V4 @' C, ]. K8 b! X5 V

% P' t* q# `/ ^! u! ]" h/ z+ _1 Z5 e# W  p3 z) ?( W& w0 _/ w" x/ Q1 @4 }, U
& q8 x  H3 P% o/ K





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