爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
! I0 U) h4 O: C$ ^# a: ]
( z9 O2 ^) S4 M% @; z& j3 c6 O2 k自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。0 Q; n; r# y! L7 m3 z3 W
# Y# \7 C$ i& D+ V
速度优化问题真的很有意思啊。
+ I; y6 ?2 ^, \* }# c7 @4 d; Z) y0 T% [3 l# z0 N5 }
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
3 ^6 B9 X! U  z& A# A7 a# l$ p把代码贴上来看看?
! I$ C1 j* A" m3 E1 w- w! ]6 ~/ H' |0 `0 K
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
# u9 Q( f5 G# J. x
数值分析 发表于 2022-9-24 23:04
  M* s+ I6 _* F9 `% y) u3 Y+ W拉下来?拉多少?
- z4 W% G; t$ P' y- S把代码贴上来看看?

: \, f) R1 e8 _5 g" x2 h" I) S0 ]0 {7 M
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 R. T- H9 z, L0 [% G
{6 Q9 G, ~5 o* b  ~/ n5 {
        comp temp, xtimesy;; o' j! _, S' O% p
        xtimesy.re = 0;
( t2 X6 d" h( ?. ~% D        xtimesy.im = 0;5 _4 |  \' ^8 o7 N5 _
        int j0 = lenB - 1;
6 h, m4 y0 x- ~. x' H  t        int    i, j, i1, reali;
9 r) _, p/ Z4 Y; [        if (lenA % 2 == 1)3 G% \: ]. x) J0 \, c
                reali = lenA + 1;
8 C# j/ K9 W4 _0 ]. J7 w' y        else
1 t4 O% U6 _, D) @                reali = lenA;
" F9 P4 e# Q" {; j7 K+ c        reali /= 2;. P* }* ]% n( b& w/ s
6 s- J. W4 @! K- A0 r' n, U# C, k
        int nconv = reali + lenB;
4 K/ K" a1 H( ^) }( Y        //#pragma omp parallel for
! ~( p' {8 Y2 v4 m- c- G        for (i = reali; i < nconv; i++)
! {/ Z# z  c% l. ?1 F1 [        {$ a1 L) W6 X! [/ b
                temp.re = 0;
# `0 T# @! T" D9 M                temp.im = 0;
) H3 I' A( }6 }                i1 = i;6 H3 J6 ~! U1 I% o; K8 m3 [
                for (j = j0; j >= 0; j--), a; i; h/ \/ Q0 w
                {
! S+ x. z: t+ H/ g: Z) l' Y- F                        /* floating date operation */* U* j& ]0 E, ]0 z
                }
: t( F$ ]9 u& w% |
        }
4 J. {: Y1 e* `8 Z( C}
* y4 T/ ?& q+ m& E7 \( }6 j7 [% ]4 p: I9 E0 n/ F8 |! ?* R* |9 I- O
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
. N5 W2 F$ v+ J7 `, B/ _- O
3 \" I- D: d3 ^* Z& J0 i红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
" j$ l0 V% T1 g6 z9 C4 B$ W; S现在call xcorr 100次,耗时78s.; F- R9 s0 `& C1 F

* h& m. u" e) v; _3 ~0 f如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. & l* y4 S- w( D, D

1 ^/ R5 V$ }* Y* Q/ y
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33, i0 j. X) B6 L$ E- V
Maybe Debug mode?

- t' ?6 h. J9 b; c1 }: O. P3 s" P
) ^7 t$ t+ F) v7 ^( G* U- D* j( U不应该,看我上面的回复。- A# T# k; z" [6 g
) w9 c0 l" ]; P- U9 O
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 % B$ X2 O2 Q" o% {6 {, g5 E
雷达 发表于 2022-9-24 23:54
" `6 |1 D( _8 H0 Evoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
0 I4 q% a+ m8 y. n9 c. E{
. T1 k! l: ^) m! e! k        comp temp, xtimesy;
: U. M5 r  `. I
* {" [& X+ g  n0 ^0 r& _7 x! P5 S5 I
这个不是这么比的吧。。。
- Y( H) m! [+ T# N
/ \/ z# r" @3 I您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。/ k. {9 b1 k3 H3 b
( [9 h; @8 t0 _  ]! c- ]& v
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 " {* k* i0 M7 ], t8 r1 @
数值分析 发表于 2022-9-25 00:20# }5 h3 ?. \- x
这个不是这么比的吧。。。
) m) }# T. I8 {
& A. v1 w2 W. B您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
3 O0 h! p9 s) P' x5 {# q

& f$ u' r- [5 Z. f# E有道理。
& r/ w: t+ L8 B所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
* F+ O. K" s) ?: i1 X, Q
5 c. P. ]  H  ^, D我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46$ ^0 ?) N" c: h1 e- j. c; o
有道理。
4 F# [/ [) ~; B  `/ Q所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

& X. D/ E2 U6 a0 d8 @# C8 \, ]你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
/ i' g2 M3 c+ o1 X" nWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:200 {( g. T9 h) Q4 J
这个不是这么比的吧。。。% E8 N+ s. c1 {

; o4 H1 C( P& Y您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
3 j+ i  B: s. |5 w
: Z6 E1 N5 D3 S8 v/ D0 ^
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
% y9 K7 S2 m$ W* ?$ L. C, B
沉宝 发表于 2022-9-25 01:48
6 @. A! o" @' X, L; Z. ?现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

: @0 N5 A" L% p9 p7 Q5 u. h2 ~6 I* m1 @8 m; o- X: t1 ^" q" V/ P( G
是的,兄台说的对。- g+ \' X4 Z7 X; _7 J& h/ w
) a) ^! m' c# a$ D/ _% h
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
. {2 E9 _, [  a3 l  N; \
1 ]# d7 c1 R! y. a) e3 M; u. y& U雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
* N' k( o  Z: z& t/ i  |9 J8 x4 T
6 ?% G: }5 z# I2 g! l# V5 D. r比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
& n$ P$ b0 |1 ?' `  P
. F& G4 B7 r1 v* `. E; }( k, i当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑   z4 A, W! P; Q5 Z3 m3 h& G7 n4 S
沉宝 发表于 2022-9-25 01:27& S/ S; e/ _/ F( }
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

6 t" N3 s$ A! E, z, \4 ]9 D$ p1 h7 ~! [: s9 [, }
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。5 D) a$ H; W" g: h

, L: D. i$ _- i7 Z. ?& F2 O0 F2 I我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
; T& k% M" V5 J又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
9 M; R7 r5 U: T1 n. n9 P5 R+ B
时间差一倍的结果可以接受。
1 @! i: X8 Y$ n& x; f) f$ y. c/ Z& C9 E2 H' V7 W3 T% E9 r) V, B
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 & }' D5 B" A0 B1 ^) B6 ?7 u
雷达 发表于 2022-9-25 04:475 x1 E/ B* ?5 R  l
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, m& j, V: I- k8 A- H: j( @7 g3 {1 C& t- `4 c

; u' \; \/ g6 b
9 A' H& T" c  X/ Y能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
( B9 k5 x) W4 [* @2 j# z
数值分析 发表于 2022-9-25 14:58
  O( B9 ]' V) D  _$ @能不能把这个也贴上来,看看和上一个有什么不同?

5 @2 ~- U6 B5 f4 u8 E理了理思路,重新做了一个测试。
! `% @: }$ w; m做了两个 vector 和 两个 float *, 都长 100000
. ^7 d) X% q; i. l. ?2 ^外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.; i" }3 u! U% i! p& F& f2 Q0 @; o

; [5 P; Z- C) x5 o8 v5 x9 O1 h- N内循环试了4种方法,: \  z  ?9 J5 h) y( {; [8 B
1. 直接调用 vector inner_product 247s $ Q3 v% y" c5 ^) a
2. vector 循环点乘累加 237s
/ G3 m3 m: w5 ~4 [1 q3. float * 循环点乘累加 204s  e9 a2 L- j6 N
4. 空循环 100000 次 202s4 s# Z  d9 [9 E5 Y

- c: f' L2 D& _8 {' r不做内循环 200s
! r! q; {1 S+ z: [" Y. r  N- Z. `& X6 S9 r5 P
你昨天说的对,内循环本身占比是很小的,大头在其他处理。; K' G6 p! O/ i2 g' u
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。6 D0 `1 @5 L: }6 y. R! s2 a
. s% p& A) a" {: Q8 w7 Z
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)3 {+ D9 A. r' b% R$ n' {1 d, J
* ~% R  r* M+ @2 W/ U# h, G
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
+ y. u1 a. L6 D5 f6 z
: C9 p- x* p+ S! l5 b4 o
        std::vector < float > vec1(N);: [" |) S. ?+ y; e1 j: {, z/ a5 e' w
        std::vector < float > vec2(N);
; e4 s1 A9 g9 U1 s        float* b1 = new float[N];
) a" l$ A8 D* z        float* b2 = new float[N];8 p/ b+ X2 J  Y. Q* H
8 N' d% F$ p' \0 r
        for (int j = 0; j < 6000; j++)
: q; ^. z; V2 f6 B* [' a        {
7 _! m$ @, h: W. ^% G4 \; d2 A; K                std::generate(vec1.begin(), vec1.end(), []() {) y/ J) L3 Y) G" P* D
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
, M$ `1 _/ }! N/ G9 |                        });7 q, o5 h. M8 w! n8 E/ `9 s8 o

6 C1 |4 `0 Z) O+ X  Q1 p$ v8 ]                std::generate(vec2.begin(), vec2.end(), []() {) O8 f" }! [. [
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;2 Y$ n& u3 B. |/ N0 G5 g6 f3 L0 z
                        });
" ]( r- Y: i' {; d$ s  {- y( q
  n  M& o# G: G% s( y0 \5 H: R                for (size_t jj = 0; jj < vec1.size(); jj++)
* Q9 p* E2 Z4 A/ e8 O0 J% I                {' {6 n: x& P# ?! ?2 z: H
                        b1[jj] = vec1[jj];* V0 w5 s) ~# J$ f
                }
1 D$ S. R0 J: ?
5 C; }% s5 l: T/ @2 A7 d+ S1 k. N$ u                for (size_t jj = 0; jj < vec2.size(); jj++)
+ H; z+ N4 g6 X. e' k8 _% L2 z                {$ o  C# I/ E2 S  J3 f. `
                        b2[jj] = vec2[jj];
/ Z: g9 A9 v1 M/ i+ `! \5 d                }: Z* ~/ M6 V* r
* q+ h  Z. N( _# Y, [: ^
                //Method - 1  N=100000 247s  8 J# F# W3 P0 {
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);; U. b* i  f$ @& s7 F. x0 {# s) L
                                - Y* a* F, N0 |! j3 C1 T& w2 F
                //Method - 2  N=100000  237s7 J% ]8 \# d2 ?; P$ B$ M* \$ l
                /*
& _$ @# F( E5 G- q; k# F$ `                for (int jj = 0; jj < N ; jj++)
, ^; R. ^2 D; Y3 h                {
9 z: e# D! N- c5 l4 a                        fresult += vec1[jj] * vec2[jj];
5 P+ e, k5 e# a& O+ V                }: M6 l* G: e5 N' P0 @
                */
# b; w8 b& v% t6 ?                                
3 ^8 ~. m' _3 q3 z2 e! H# _( A                //Method - 3  N=100000 204s
* G) q8 ~/ {# _+ _  V& m                /*9 m$ Y. a4 ^  m8 ^0 V( T1 b0 |
                for (int jj = 0; jj < N; jj++)
. Z# d3 `0 g: S2 K+ y6 q: ~. U* G                {
4 p0 E1 y  W# A! P                        fresult += b1[jj] * b2[jj];2 p$ }0 f, p; @: r7 Z% a
                }
' P" W+ g3 c0 _                */
  W; g  m7 a. C0 [& W% [, D6 X- K+ }6 K) h
                //Method - 4   202s
' I! v1 d1 n0 |; h                /*/ H8 N* g- m$ C- B" x1 b" f2 j; i
                for (int jj = 0; jj < N; jj++)+ X3 @& ?- f1 A0 k/ @8 k7 z
                {
+ Q' P6 K8 X7 G& V                        
1 Y6 j* P7 u( X- H                }
4 ?" ~7 e% |  j: x' a8 W                */- |0 k" K: S9 q9 p3 y+ R
                //comment out all methods, N=100000  202s               
, v  s8 Q: B: g6 |" R        }
+ `3 k6 v/ o- y0 }: \3 t. E# W0 ~* m9 }+ h% Z# z
        delete []b1;4 ?* U3 ^% ]7 A' g5 U
        delete []b2;
) Y9 B2 V+ T9 Y% N4 z7 G

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
8 j: @% e; Y% {& X4 K- Z6 `0 t6 P9 h5 e2 U
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?3 ~0 ?! U3 Q' y& Z5 S- @

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
4 d" t5 y+ ]. o/ G瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?6 {, `  q8 u* \2 \4 d6 t- q

% J/ D+ b8 q% ~; [你第二个试验里面的j在循环里面又重新定义 ...
/ p' s( N4 d% B/ \  D% |" w4 R/ j
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
8 _& d6 U7 G' O2 `5 f& q
; X: M4 @( x7 g+ j) r. D2 Q4 X5 [不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:166 G, {' h; Z3 Z- v( a; {) ^4 T) Z
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL0 H% R) X4 ~; ~0 h7 ^7 n

: x- k& k; [$ r' Y" r不和它 ...

# b; e3 j# }0 h: k, S- C8 h5 ^# @' Z) B
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。: X9 {5 m+ d7 a* m' V( e
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54$ N- s7 K* E  i1 l, r" c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" {0 M! Y0 I4 V0 E
{1 ^" }" z" _2 A9 a) Q0 g3 i3 r# ^
        comp temp, xtimesy;
6 L  J. V9 k% w) T4 z1 g" M
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
/ V0 k; e: Z" \# L* J( O内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
$ E* M# l! R1 y6 N9 u# gVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30+ u/ Q+ L* a8 o
理了理思路,重新做了一个测试。
, t: G9 E! \0 J% \做了两个 vector 和 两个 float *, 都长 100000& p& I7 [1 t' y# o1 c# E
外循环 6000,里面先做随 ...
0 o+ M5 N/ [( r  e* R
这个时间是从哪里开始算的?8 ~& J" B# s# Q( ], d1 g. z- C
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
8 |2 I9 e6 n/ _6 ]按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:391 ^+ A7 W0 V4 `  `+ p
这个时间是从哪里开始算的?
# u9 B4 F$ c1 y( B8 @  t8 |我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

! p0 @. x& @  \我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。+ [0 \% H! x9 i. ^. Y6 \+ ~
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。# b# i0 h$ C" [# p
与此对应用数组(指针)花了2S
" j! J& K0 i0 a5 T你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
- h2 e4 S8 v9 _7 O( ~' {  y" }& P% x7 hvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)2 U# G2 h) w7 R4 y+ s; T) p. |
{
7 O8 e$ f6 A. Z& z) ^        comp temp, xtimesy;

1 d  f3 Y& v( R1 X! R* G  ]# I$ z我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗" s* X6 f; L4 N. X' p
9 K" `2 ?3 r5 L

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29( S( v$ B; s- N4 ?9 z
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗3 o6 l( y* ~$ I& |( `
% f( F: L  V* ?+ S. Y' ]- j
...
- m; I/ L" `% m' @( M- p- V
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
* ~, j+ U: k. c2 M: h
# q5 K; D. q" Q5 ?4 u雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ! ~+ D2 U$ Y# V0 b& O
1 {4 `' c0 l2 U+ I# c7 f  @
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
; o* y4 }* ^: v有空时我会试试 SIMD和并行,看看能提高多少。
# F- F/ d. ^0 n! V2 B过去7、8 年没有正经用C++ 写过东西,没有 sense 了
( b2 x2 {" E5 w% Q( A: ]1 i谢谢大家的讨论,I learded a lot.  红包已发  3 W* u5 G4 Y! D0 S
+ p  g- c' c$ Y4 B1 x

% Z' q" @. Y- d, X0 I* C& H" S8 b& A$ O; _
" v$ [0 p+ W) P8 _1 r. F





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