爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
  r6 q, Q& Q0 P5 J% f3 ?& P
* f% J" o& T6 u  V7 e自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
4 Q. `( n3 o9 ~: A) R9 o! H! C9 E0 T1 k( k+ l, `
速度优化问题真的很有意思啊。- G- E, g, j% r- U0 b3 J- y1 ^; S2 Q- q

8 P. T7 x2 H/ B# v1 V欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?# m4 ]' h1 b/ N1 u' w
把代码贴上来看看?1 \+ R) f( |9 o1 g) e5 `
% \* r" Q. i2 F! {. l# _* w0 G
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 : F; Y1 U+ _, G4 Q$ V# e
数值分析 发表于 2022-9-24 23:04  u: R$ X+ u- U) G4 {, W6 x0 L
拉下来?拉多少?7 m! p/ c5 o  x6 k# m& A5 ^
把代码贴上来看看?

2 p  h2 m2 _1 I) Q# b" s# x' f0 k2 F+ B2 j3 E
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- u4 G3 N* g1 Y2 s{
$ N& A! z" k" Q, n, L8 }- U1 b" @        comp temp, xtimesy;
: y5 Q* H/ S! e( A: b0 J& |$ Q        xtimesy.re = 0;
' A1 ~/ A: ]* K% J1 I        xtimesy.im = 0;; \/ ^4 T& l3 b2 w/ Y! u
        int j0 = lenB - 1;
" F4 h  @9 n0 v4 _        int    i, j, i1, reali;3 i" i, h+ p# K4 ~' E
        if (lenA % 2 == 1)
) @9 d6 R. u+ I& O& z" `                reali = lenA + 1;
9 J! \1 g# P  Y. m" o        else
. D+ Q1 o( ]% T' B5 K1 u% H0 V                reali = lenA;
6 a  y5 X* u6 v2 f( p% L        reali /= 2;: p7 M5 ^2 _! z1 P

; k, T5 m% B- F' s# ?        int nconv = reali + lenB;9 t3 T5 e) J3 [0 G: w" i
        //#pragma omp parallel for
5 y1 [' h* d4 W0 D        for (i = reali; i < nconv; i++)2 G8 F1 z" M4 Y( C
        {
' W% V, S4 a7 Z% _, b/ a: E; }                temp.re = 0;. R$ l" H. h2 a6 R
                temp.im = 0;; f7 ~4 Y. a9 e8 f9 @* m
                i1 = i;
# t% Z: g0 l$ X) D# _% e7 B. d. D                for (j = j0; j >= 0; j--)6 X3 g, ~( F! C. p5 |! A7 W
                {
' j/ D, |' R9 }6 b                        /* floating date operation */& T2 \  G+ n8 j0 W
                }
1 s- W1 H* E1 Q4 M! d: ?) C
        }$ k  U9 V+ W' {* ~! @0 H7 g- x
}
; h/ _. ?' I0 U  ~! b2 B" [* p) U5 q4 g
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样6 Z/ g( d& H! P, J6 [0 g% @
! e+ N+ c& Z( S1 y* i
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。0 `8 @; i8 D8 X% ^* _
现在call xcorr 100次,耗时78s.
% o- s" v0 w' m& ^7 X( r" t& @" p8 [
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
* G7 S+ g; z$ J0 v- I  i1 H6 C0 z8 L* x1 e' c

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:337 k. e6 \. q6 T5 F) \; g: E7 J* V$ H
Maybe Debug mode?

$ K1 |9 _; X4 Y. a4 o1 v( H- x$ H6 O. H6 Z% y
不应该,看我上面的回复。* x9 F' G- [2 h7 F5 Z4 e
) m0 A( p- \) U/ S9 y
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
% n' y+ \: P0 V
雷达 发表于 2022-9-24 23:54! Y" J3 i7 n- @
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 l0 F0 x5 X  z3 p, D9 T
{
: f1 F" A) P, B        comp temp, xtimesy;
  ^7 d7 W1 b6 ?
( U; O3 a7 l- T. r* T
这个不是这么比的吧。。。5 I5 @6 B4 x* W  U3 M* ~' G) h

; E* E+ w3 Z1 G) {# l/ V( M9 I2 g- U您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。3 ^( s! {. Y3 [! g1 |

! c' v% k+ N! m5 J而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
. h3 h8 t+ W5 F8 i5 P+ n: Y& @3 }& E
数值分析 发表于 2022-9-25 00:200 A3 U. N) l2 y  M3 t
这个不是这么比的吧。。。
, I% i8 T" t% l4 ?7 l7 Q
4 W4 n) t0 F. ~# [$ K3 A您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
4 F; v6 o% N8 r7 ?3 I0 k
& r! v* N" S( G! E! F
有道理。: }6 j& h% D$ Y' J, E1 F" |
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。/ i! y: F. ~& J  Y+ f

- M' ]* |1 e, u& o- u# t9 K我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:465 ~" M+ P0 G7 a5 [
有道理。
/ |* E  ]3 i  ?2 W) f$ j所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
: {2 Z* y9 g% G! i( W/ K
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
. q- P) g4 \; D0 t5 T# [Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
$ w, T" k1 a2 M) n9 o$ Q- V* I7 _+ D这个不是这么比的吧。。。
# o3 e9 f) @3 e$ `
5 ]+ C$ C" B5 d, l9 d* C# p8 u您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

* D4 u2 _& \% i! R1 X' N) s& \
+ `" [9 r' h' E; [$ N& ~4 E. w$ I现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
; o- z3 M6 c) }' Q
沉宝 发表于 2022-9-25 01:483 N1 {# ?6 Z# P5 c* A
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

1 o; [# _1 J% S+ T( ]- E; G  D) d/ Z
是的,兄台说的对。
" \6 U7 C" w- y: E. E( T
8 B* J, P1 `7 E: b: K0 R/ ~2 l& ~. h其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
' ~1 m7 F4 n7 B8 V! d$ a# |. V) C, D5 I3 o6 j
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。) ]" D0 v7 T2 q% ^) r

& U% L$ e6 X$ Q8 n9 k比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。+ U( E' s  x0 C; y7 a; k: R8 H
  \) G! h( a  ]$ d, m4 r& j6 j
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 , w9 Z+ i8 [3 z4 T: j* k0 |' q, d$ e0 \
沉宝 发表于 2022-9-25 01:27* f( J! I; H' Z+ s
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
, y- ]& Y7 K1 A+ u' ]

  Q2 c1 m: X' k4 P& e! ]又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
2 B" i/ h0 I* t& c* R! z6 ?4 s. S4 D4 R$ U* ]
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47$ w/ r4 ^, E/ V  P. @$ z4 b
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

6 o+ Q5 W+ o4 U2 p" c4 l时间差一倍的结果可以接受。
) q4 H+ `9 W8 T. x
3 A; P* r0 S! Y/ |你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ; t( s& ~9 q0 ~7 P+ E
雷达 发表于 2022-9-25 04:477 q2 M' c0 a& `% p4 J* @9 C( N6 [
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

& Y  y! {0 i' g" l5 L! [/ o
: V1 F# `: w7 ]1 B& P2 ?) A4 v' O# ]% {8 ^7 j+ V* }3 W8 ]

2 B7 d4 F1 T6 A2 B能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
' L# ?, J+ R( J: T1 v% i
数值分析 发表于 2022-9-25 14:58
0 X4 T7 \3 D. X/ ]& O4 C, U* W能不能把这个也贴上来,看看和上一个有什么不同?

! A4 ]; [( i& G  v* F5 x1 F9 A理了理思路,重新做了一个测试。! h! V: X7 Q/ G
做了两个 vector 和 两个 float *, 都长 100000
* y* L! ~" U2 `. Y7 A外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
3 c8 z0 D# h4 q  s  }- X
4 `1 w8 d; {# w( `8 Z7 D内循环试了4种方法,9 Y$ A# \' E# J3 K9 n% N/ s- N/ j1 r
1. 直接调用 vector inner_product 247s
9 B4 I. Y" o5 E& d2 ?1 X( N2. vector 循环点乘累加 237s4 [- H6 F9 e. [
3. float * 循环点乘累加 204s" y/ t* M3 P$ m8 i8 [! f
4. 空循环 100000 次 202s: U; s# f) w) K: v/ i

7 w8 Q8 y& D+ d5 Z7 q不做内循环 200s
& v# Z2 s" y  N# k* t4 X. O
! ^# |5 i4 B6 j# e- [你昨天说的对,内循环本身占比是很小的,大头在其他处理。
" b3 a4 B: `( k4 D+ K另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。1 ~/ q2 D8 ?/ N( Q
- l( T& E- Y. i; s0 P- l( x
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
$ \. U- S5 k8 b  ]* k6 k# X8 k1 j6 H0 U0 `
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
, I7 r! Q' y; p/ t
- q" }3 Y; Z0 y0 _3 R
        std::vector < float > vec1(N);
% E! ?2 S2 u' G5 z0 J& W# N        std::vector < float > vec2(N);  |0 M( ~5 \" E  j  z
        float* b1 = new float[N];: @2 |' X+ A9 x2 W+ ?& z
        float* b2 = new float[N];
+ ~5 M: _0 V, T4 @( h0 t9 n+ M' W  G6 w7 \% J: P
        for (int j = 0; j < 6000; j++)) L7 d' t  M/ }# y8 ~0 E: W! _" u
        {3 `, j1 c" e8 l5 f: B" P' s# N
                std::generate(vec1.begin(), vec1.end(), []() {
3 _' ]: C! S2 ?0 g                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
5 V4 i) u8 w0 p( S2 g. u                        });
! l! X0 T- B! H) _1 C. z# R4 g+ Z
" X! Z$ Q; \& {6 o; d                std::generate(vec2.begin(), vec2.end(), []() {6 C5 b; I  q- j3 p
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;7 j  ?4 A9 F& [4 b" a7 F- q
                        });
) V, k  H7 d1 f# F# d6 D$ q* Y0 i/ @/ w0 z1 x, S( F+ I
                for (size_t jj = 0; jj < vec1.size(); jj++)5 B9 ?9 G- d5 s
                {9 T  H" `7 s6 U7 s
                        b1[jj] = vec1[jj];- A1 c! E! O& P& I
                }2 Z; v8 w, k0 N, N9 D

) t) f8 |7 u1 X/ d7 e                for (size_t jj = 0; jj < vec2.size(); jj++)
( M" X6 G5 r) O                {
- i: U; \8 q' d' _  I5 h                        b2[jj] = vec2[jj];5 n' y) h/ m( c5 `: M
                }
% Z3 R- m. _/ m3 {$ r4 r
) ?' x0 l9 v+ Y' U                //Method - 1  N=100000 247s  9 K% b' s' ~2 o/ R' P
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);* Z% t2 F) E9 P; K5 ^( W
                                
0 q5 C' X5 d& k% [0 x" u8 I  S                //Method - 2  N=100000  237s
0 E3 c% {6 z" ]. [4 I( ~8 z                /*! N; O9 f8 Q. f
                for (int jj = 0; jj < N ; jj++)
/ K8 v  b: i) U                {1 b; S, s2 E& L" k: g. `
                        fresult += vec1[jj] * vec2[jj];
. `# I: X' f" F2 ^' }                }
$ k0 x& Z, C4 M1 o' x5 K                */& X8 J. F& W  x" Y" y9 Y
                                ( X& q: a5 n# `8 ?: M% i2 }
                //Method - 3  N=100000 204s
2 M; g, E3 U8 h8 N+ `& Q                /*
+ z; `. T, a% ^2 p  y3 j                for (int jj = 0; jj < N; jj++)
1 k% f3 Q! h5 R                {
' z6 F8 J4 q: f- r9 S1 C                        fresult += b1[jj] * b2[jj];  M& o/ @( ~# L: I; i/ S& ?
                }1 _; Y# r1 N# W  W
                */
/ L/ R; r; s" @- n. F8 X$ F0 R6 E2 t! h; T
                //Method - 4   202s0 p! A0 g$ \  M8 S8 V
                /*
; X9 i( `0 |$ L5 N. A8 C# c                for (int jj = 0; jj < N; jj++)
3 G( G6 H& T3 y0 C) [: V                {' J& X' d8 B" u3 T7 t
                        
8 |* G7 {, _0 c+ c                }& a% G6 r3 x8 o
                */7 G9 S% H7 d6 g3 J! V' H
                //comment out all methods, N=100000  202s               
+ c" ]2 n) w0 m( C2 r        }. M2 U" N8 j# _
6 D2 A2 K# }* h0 o
        delete []b1;
; t7 Y- y7 C* h) F* i1 V        delete []b2;
+ N# L) h9 t; d( n: [

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?0 g' A4 ~4 _" L) |1 K8 M8 h

5 _+ V! v& [0 K$ j( O- D( M: K, w+ P你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
! V9 i# v2 W; F
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15' A  L* E( }1 y, ]. a' M
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
% H$ |- W( f. i& T# v1 T' f
3 W$ U# B/ Z6 z+ b! z你第二个试验里面的j在循环里面又重新定义 ...
+ s! O, z( Y( {$ ^% M! M
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
/ ^( T$ u% L/ Y1 J$ D1 M% a. L/ t% d/ J4 _8 c8 S7 {: `" i7 b
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
# d9 N7 Y9 @7 I7 B: g9 p& p内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
& s/ r7 Z" o; w% _6 Q
1 A/ K: Q  n8 f1 g+ V2 O. A! ^8 e  L不和它 ...

6 g, q# _0 }9 r$ d5 W8 M
6 _% V2 @. k3 T* d! n不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
/ U1 _- H) n- e: D- s: O9 E8 D3 k8 `6 ?后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
9 D% v) f% P3 R; C& F* Pvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)' Q6 A; z2 v6 P
{
9 H1 j/ q7 b# \  y9 y/ _        comp temp, xtimesy;
( O" Q/ ^5 [% a4 j. R* v
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
- @9 y, u) j- k0 D内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?# W; E/ L4 H, \* y
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
  o" ~8 c( F1 X理了理思路,重新做了一个测试。4 W; o: J$ y! \/ F0 u
做了两个 vector 和 两个 float *, 都长 100000
1 H% ^8 X3 r3 ]7 j, u* H外循环 6000,里面先做随 ...

) Q  y3 `6 E/ ~) a& b这个时间是从哪里开始算的?
) z6 L( P& O2 g我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。! G# G: C7 p0 L, S* e: b
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39' A( _6 ^- ~+ i6 v( B
这个时间是从哪里开始算的?) t" g/ g3 }4 L; j* h
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
% K; P1 I# a  u1 V# s  K- i
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。0 D# v0 W% \0 {% R7 v( Z
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。  _& g/ Q2 w# ]
与此对应用数组(指针)花了2S. x1 U- }3 F: {/ e0 h% |
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
. v9 r! c* @& e5 @6 Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
3 ^( l9 V: R0 R/ k{
; s" @9 L0 R& t        comp temp, xtimesy;
7 V: Q+ d* U; u1 f( R% h0 k7 K6 p; z5 N
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗- q* H; O' e1 \1 J% @* a

: V/ A. Q5 A4 H  C+ ^* _0 @  K! D7 v
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29+ D$ R7 |# _) x+ {, x, C# f
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
8 f! x% C5 ]% `0 P2 d$ x& Y+ g1 W+ t& B* S4 {2 F
...

$ L# A  P; n/ p) d. y! w0 S7 t你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
, |: y* N. d" J, X$ x
# f( e3 D! g8 Q; p" b9 p* V雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
, r6 Q! C% E, q3 [' x1 y  {8 t: e. W. [( y7 Z: O, P
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
4 }; }0 U( c  X有空时我会试试 SIMD和并行,看看能提高多少。8 c. o# a2 d( L( V: q
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 5 W3 e5 U8 t5 z0 r$ ~- f
谢谢大家的讨论,I learded a lot.  红包已发  0 l2 X8 x. K1 p. }1 O7 C

, n, x3 h* O$ J& X4 @! I1 z& P6 ?3 B: B
2 U8 K$ w% f9 r: p

* b! L" J& X' ?




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