爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?4 E4 ~2 J2 i0 q% H: O) a, F
1 J' W* y; {6 \. U1 x
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。2 ^7 s9 l2 P  x$ {7 G0 ?

. L& b& S1 H+ F! S' m速度优化问题真的很有意思啊。
" ~7 F+ D; A9 E' \& W$ J/ l
# A$ P: u+ y' |; ]" }) e4 T& Z欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?# E9 V+ l( N9 _1 m0 o* {
把代码贴上来看看?- u7 g- b! U( S! Y

0 i5 n7 }0 q/ S5 g难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ; R7 Y* y6 l" W: n( o
数值分析 发表于 2022-9-24 23:044 W8 n' l7 B, L$ G
拉下来?拉多少?
- O: _# C- d2 o3 {+ k2 q9 O把代码贴上来看看?

9 F' O) H7 e0 I5 ]7 L5 R& Z2 v
, }3 K( u/ W5 ?9 t5 ]void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
& E& B; N7 D8 D  @1 l8 M9 M: }{, ^( K  K1 J% F
        comp temp, xtimesy;6 {8 y. F( v1 U5 A
        xtimesy.re = 0;
( Y2 ?: D9 p+ [& l% R( M        xtimesy.im = 0;9 D: d2 A3 q) {+ {- |" l4 y4 ^& f& k
        int j0 = lenB - 1;
7 G3 E$ L& ~! I) W* d        int    i, j, i1, reali;& o7 Q# ^, g/ E7 H# o
        if (lenA % 2 == 1)
1 B: ^- O& N  v6 x; q  y                reali = lenA + 1;
2 K: }# s. A, U# ^9 G3 r& B        else
' a5 \, I, k9 W* ~4 Z                reali = lenA;5 ~8 ^6 o- E! ?1 _5 y+ `4 }6 y
        reali /= 2;
+ t1 E& U: |; [1 T
$ _9 I& Q. y/ o" Z+ v$ m* c" J        int nconv = reali + lenB;1 L( y1 x3 Y7 J( C
        //#pragma omp parallel for
+ Z0 O6 m2 G- q8 ~$ r$ g        for (i = reali; i < nconv; i++)+ J# F8 M2 Q1 m" f
        {. Y, x+ Y0 A8 T1 ]
                temp.re = 0;( o* g0 s5 m, N! y; z# T* y4 I
                temp.im = 0;( ~% i# U2 @2 s
                i1 = i;" G, [2 i+ x- i8 Z
                for (j = j0; j >= 0; j--)" a* W2 _, H8 _" i  {
                {( ]0 q0 E. h. Z( ]0 h4 n
                        /* floating date operation */' W; G. D8 F: @. ?! u
                }
0 M0 I. d3 g, Q' a
        }
! n6 n7 V8 c8 h}
: O8 m# W: f6 Z9 \" d3 e+ d  z$ U# z; e* a. _3 E* M
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样, D$ A8 O5 m7 H, I: s$ |
+ x; W- E" d) z9 u$ W, @1 J+ ~
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。& a+ ?; I8 F" H& N! [1 Y
现在call xcorr 100次,耗时78s.
& Q& h! Y  F# _2 O) k. P9 r$ k4 `  P
. t4 L& y2 o4 q# N! ~" K5 `如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 8 W/ I, a8 K+ R' u6 v* ]6 y

3 O# l' S! K* q3 @; l( W2 @
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33. ^- L' b6 G3 ^2 E
Maybe Debug mode?
# }: Q; \! r9 X
( m# K7 @3 X( z' k! L; f  q1 l
不应该,看我上面的回复。& E. F/ e& V. F8 N/ a' h

6 s' s( I1 C5 A+ u我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
+ K4 `% ?+ t. L; g6 z7 E' E
雷达 发表于 2022-9-24 23:54* Y/ B6 b1 o1 M3 [7 t
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" B2 _3 ?# R* z/ w* O7 y. _
{
  z  u4 X& c  d2 a5 Q/ h        comp temp, xtimesy;
) t$ s$ W/ d1 }4 U

. e" ?: o8 I  P) S0 S. G# M这个不是这么比的吧。。。( f5 p" w" C3 j6 X( y

3 u7 ?" A3 y  t$ ~! k+ x您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。+ I: S9 Y: }/ g0 M: o/ u3 s5 m& e, ?
  @. {4 A" n( G+ G2 H8 A
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
4 ?9 @2 S+ i* ]* r
数值分析 发表于 2022-9-25 00:20
: U6 ]" G: K2 A& c* o; B这个不是这么比的吧。。。: \3 b: Q3 G3 ^9 ]
& L" `# [" P. H8 S6 L2 B- P
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

1 a  g1 P/ A3 N
0 ~1 P: o% E5 @" B3 v有道理。3 n7 m$ U* z! P5 t0 t* u
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
1 r3 G: O1 j' e9 E) u1 H) z: ^/ ~9 {+ q
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:468 ]7 Y' n1 n! |6 r+ Y
有道理。
; `5 H- t4 P0 o$ W所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
% y" `) B1 F9 ]6 H# Y  \
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多1 u: A7 I" z7 d; W  b7 G- n
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20) E* f! {6 q8 L7 r- Y: D; y! [
这个不是这么比的吧。。。
' F: N9 Y* M% k: }4 K
7 I, D; Q; `+ _# A( i# t( a  B您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

" ~" z. L' D% V+ a0 k9 z# Q8 q9 u7 w, r7 m0 P, P# O3 J
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
9 G0 A0 k" N  I- ^! L
沉宝 发表于 2022-9-25 01:48
2 n1 [* v5 d8 e( Y# Y& ?现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
4 M3 U  T$ T" h
: t2 R: u# y& y( a% C: a$ l' K
是的,兄台说的对。
6 ]) k' T) A) j) d& H1 R9 i) R' @& E
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。+ c5 S( M- i6 q2 H0 w# H

8 J* q2 t, `) r2 {* Y% L雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
% k- [4 k& }( J: b9 A. G/ O
" ]" r0 e# X/ T- C" N( E比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。' P4 \. @3 q- Q) G4 ]
/ c1 f. Z, m% Q$ ?0 Q( w. i1 L9 |, n
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
' O, z( f9 y% M$ ~
沉宝 发表于 2022-9-25 01:27
, G% `" i+ W7 F$ C/ m0 j9 `你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
% P5 n0 [  f; K+ I7 h

3 G3 F9 V) l) W) G/ E& ]" y又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。) m, ~" p1 q- ~3 M
, `# u& U, {9 f9 [6 S
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47+ {/ q2 C8 S& D9 g$ y% M. e
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

" |, Y; K& t* w1 H& C: x时间差一倍的结果可以接受。
9 D# j3 \9 a$ g: R. K7 W
( f% D; p8 S" |/ t& d" L# ^. h" M- \: C0 }你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
# L$ l2 `" F! g$ {1 A8 K
雷达 发表于 2022-9-25 04:473 e& q" Q5 f. m; W4 x6 o
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

- o: b9 A& `/ K& R. @; M. ^2 _: P0 w1 l2 B0 q6 v
& x: L8 _5 Z* R* ^0 Q2 F
6 a2 I4 H4 m. \. w  \# G
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 $ g2 D% f: W$ b- Q. M' M6 P7 z5 l
数值分析 发表于 2022-9-25 14:58# L0 T! d7 N: R1 r4 g# W
能不能把这个也贴上来,看看和上一个有什么不同?
! R. A, l# _# H8 V. M7 l' G
理了理思路,重新做了一个测试。; X- V  B9 H4 ~
做了两个 vector 和 两个 float *, 都长 100000
- ~9 D6 E* J  ]' M# y$ M外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.4 ]5 P/ P+ j# w8 D1 W; w, G# F

% m) x# A' r' X. M) `内循环试了4种方法,- B2 c2 N; a! e8 G5 ~5 r# P
1. 直接调用 vector inner_product 247s & o2 z9 k- Z+ X$ [# _
2. vector 循环点乘累加 237s; ^' }6 f. ^) t( {# I$ y
3. float * 循环点乘累加 204s) x7 C& d5 u3 E5 D' Q
4. 空循环 100000 次 202s: {1 {( |0 b! x/ o/ @

3 y% K' ?5 t6 t5 A; f+ G4 D不做内循环 200s
. q% t- j9 I6 e% P8 B+ J, z9 _
4 ~; P/ w$ A% y. t# Y! V你昨天说的对,内循环本身占比是很小的,大头在其他处理。9 K8 O0 Y. m  }# p+ v7 J' W
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。8 C) k/ N6 F- s) Q: v2 ?% _/ j
$ p3 O! g* i; b
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)* _3 H" f8 }3 D3 ?, i$ s6 |
8 ~$ N1 k6 E6 g# s! }
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)) w! [$ T: g2 \

5 ~3 m+ w8 X; P5 e! o
        std::vector < float > vec1(N);( w( n" m% I/ n4 t3 T1 R: Q
        std::vector < float > vec2(N);" s$ ]6 N" S( H- s
        float* b1 = new float[N];, Y* Z+ O  D' V/ `& m/ a
        float* b2 = new float[N];
- b  s- C% i5 H. b" \9 T) Q7 _& C; J  |& h( ]2 @) h: t
        for (int j = 0; j < 6000; j++)/ u, D7 U$ D  X+ m* N3 d0 p1 x
        {4 G; ?2 `) k1 p0 w+ l6 Z6 y
                std::generate(vec1.begin(), vec1.end(), []() {
# I' E' i9 ~' l4 a7 _                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
1 n! S6 n4 r% Q" C                        });  _; @) U& U# v' B1 t9 g

3 H- X( Q. g& A" H                std::generate(vec2.begin(), vec2.end(), []() {
! i2 K0 V- w# g/ k- b                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;+ D& w8 T% d) I& Q( }( {
                        });2 I& S& W! I4 R' L

: X# L3 {% \5 @                for (size_t jj = 0; jj < vec1.size(); jj++)! }* P) _% Y* [- A: f& T" D
                {
% m) v' i5 r( A- @) d6 [! \: f                        b1[jj] = vec1[jj];
" f; k* x6 `# V% k( j                }. y# B. P. V4 H. j- S% h% C

# z# a8 c" V6 |/ l' \                for (size_t jj = 0; jj < vec2.size(); jj++)
  x; Q7 I1 Y% E% `: k  O# ^                {' B: U0 Y* N, m+ X. l
                        b2[jj] = vec2[jj];
: s- }6 K, ^  {2 I; [+ T$ F                }
1 B/ l# m. l+ p7 _" r0 W: r) T+ C" Z1 j2 j* g5 X2 {; e
                //Method - 1  N=100000 247s  
3 j/ x/ X  M) y( ^3 _, _                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
0 ^7 W+ A, L/ \& G/ a" y                                7 P- z3 ?: ?/ s: ]* i9 B" r$ I
                //Method - 2  N=100000  237s
' N% \$ B/ s" D" ?1 c' k$ I                /*
1 \& v* j( A8 r0 d7 L. D* d                for (int jj = 0; jj < N ; jj++)2 j; B6 P- ?8 K  J  B  z
                {' B, p  V+ G8 F" ]/ B
                        fresult += vec1[jj] * vec2[jj];9 p6 y' C2 m7 d- {$ {2 q- w$ \" r
                }
& Z& P; o9 Q/ i5 M2 f6 ~* b                */2 z% u* P$ V; H( B" @9 ~# i
                                
4 V( z! ~7 G) F5 F                //Method - 3  N=100000 204s
5 ]$ c; s+ K% X, C6 C                /*5 v: e% X1 i0 h: t* W- Z+ E
                for (int jj = 0; jj < N; jj++)- u/ j* X" l$ R8 r/ O9 A5 @3 W
                {
8 Q# H) ~4 `% b6 I3 a7 \: Y* g/ }                        fresult += b1[jj] * b2[jj];9 E" V7 N  t/ W% u$ k2 q! _
                }6 p* K4 l' ?+ I$ j
                */
( ]9 w2 z7 ~* N) S: i, o7 z( h1 @& G( X5 u5 v
                //Method - 4   202s
$ W4 Q9 q, T4 n  t/ m                /*
. m$ ~! ]' H# Z, {6 z, D, W                for (int jj = 0; jj < N; jj++)
3 D( L/ k( N; L: C8 N9 o                {
% F5 q) R% ^- J1 H* ]3 R( v7 G                        # f/ j4 A3 a9 `0 b" F
                }
+ G5 c1 K9 \% K+ a* i) B* O: e                */, e3 Q' a% Y3 X5 L0 G2 @1 \
                //comment out all methods, N=100000  202s                - {6 G9 y9 }9 I- U$ \' c
        }! p& S% I4 y- _! L5 t
, c6 a$ l" K3 ~  }4 t# {1 N
        delete []b1;
" V8 v2 m" G# x; h        delete []b2;

% `! r( j* j" a8 `; H. ]) v
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
9 P5 @0 {( w2 ?6 B$ L9 O5 W+ O2 T& F/ Y* x9 ?% \8 ?- r
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?5 Y% ]3 V6 |5 E4 t

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
8 _5 ~# p4 V1 C( b) K) i9 }瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?6 ]6 q, B/ [1 ^  r+ J/ c

7 [( b4 }0 P) B; y你第二个试验里面的j在循环里面又重新定义 ...
+ ^8 |) n, f7 f: x" X
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
! z0 w: B7 K. V2 W# E" I6 W7 F( f
( j7 }7 X  r, ?7 h6 O不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
- O. L4 ]. |9 Z. h内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
' b* e6 w+ ?6 U
1 I6 p7 C! M% W  K$ M不和它 ...
# Y) h% b. O2 t1 D9 }# v

3 X7 N) M) q6 ?9 S- c# v. d不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。9 H3 ~8 S- g: V" [8 K
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54: ~6 i" o9 [1 k$ v
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 O  M7 ~6 o% D2 v+ L1 e( k- R* h
{
: N/ ?* b" {3 c9 e9 ^        comp temp, xtimesy;

! d. B4 b+ d3 X这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
7 F7 E4 u) h& A- x7 Z内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?, P: o9 I& g: _4 r& B/ G
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
1 F9 |6 Z7 |( W! e2 p& s" X理了理思路,重新做了一个测试。
1 d. _: Q8 X! T, _0 F* W做了两个 vector 和 两个 float *, 都长 100000' ?! W5 E" m$ E* x- ~( I
外循环 6000,里面先做随 ...
5 i9 ~# k: V: q7 ~0 {: e* c
这个时间是从哪里开始算的?3 P$ T+ w" @, v
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。9 @) d* s& V! S! d! D$ @+ o
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:395 l1 P$ d( E% P$ j9 n8 _
这个时间是从哪里开始算的?
% D% j$ S4 ~3 @, b5 h2 g% H. X5 Z我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

$ r! z( R- T& ]# C我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。+ H) N8 `1 Y  T
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
3 u# C: H- c3 z; S$ i) ~) q2 M与此对应用数组(指针)花了2S
4 F; \6 S# R; y( [0 Z. G你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
8 [9 K: S# C# x) a' R: o  \4 ]8 b+ @void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)& u) Z& w7 B7 ^8 o
{
- e: f$ u6 d0 E: K8 U3 T        comp temp, xtimesy;
: r9 N# D7 b) B: |/ p& Y
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗6 r9 J9 }% b/ b5 `9 O8 s
% y# @! `2 K, S* ]4 f* \6 [! N# k

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29" ?1 M, [: f7 ?  a' }. Y
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗$ e* t4 C- {% \! x

# ^' d0 A; K( G2 W) c( O2 T$ n ...

( I& _  h, s9 }# a: F( J你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。3 Z$ M9 F: \+ b+ _) v6 s
, c4 a% p% C. f1 C7 A
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
8 W6 Z- D* z+ y% n4 Y" w3 C
" S! Y1 T+ w& m4 v5 C1 A是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
  g. R/ L/ u5 R$ [% o9 H有空时我会试试 SIMD和并行,看看能提高多少。
9 j+ w" \* t' g+ U  f' \- a2 D过去7、8 年没有正经用C++ 写过东西,没有 sense 了
! ^. ?6 q5 k; M. P5 V$ @- v谢谢大家的讨论,I learded a lot.  红包已发  
9 X  W: M0 S) R" _+ `1 v, E0 z: ]
, a, [9 [" d7 |# j" z- |

, S8 j% i0 x6 R: p7 [* Z3 x# u! X( G" S- J





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