爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?  ], ]0 V8 K0 N' k0 I/ o7 e
" w' ~: D- f4 y  `4 ]( e
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。& q1 H8 g, z0 _& T( K

& d4 G7 I' f/ R) X速度优化问题真的很有意思啊。
; |4 @6 J2 g* D- |- `& O" q7 J# Y- q2 P' N
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?/ K& h1 a; z' `. q' H. M0 a) [
把代码贴上来看看?0 v% i& z; L! J4 [: e

% S/ Q" P3 L7 i8 i- C) B* G* q) Q难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
( D$ a, S  m1 a6 o  i
数值分析 发表于 2022-9-24 23:04- f& N* O# q1 f1 M) `
拉下来?拉多少?
" R; p. c) B% @7 I# d( ]8 T9 ^把代码贴上来看看?

, D( N' U7 e! y( b$ H. x& c1 }$ k) o; z, @: e1 j& h
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
- O! N7 A$ m4 j1 f0 @  ^0 E{
+ U6 }6 }: p/ Q' m" Z5 u$ O! ^! P, C        comp temp, xtimesy;( P& }" y5 k6 h; y1 n+ p, s
        xtimesy.re = 0;( i0 k* o* `! u' Y, q  r& ?
        xtimesy.im = 0;
) x( _5 b4 B( t, p8 T, J        int j0 = lenB - 1;: C1 \  `) k$ N8 O5 E; n
        int    i, j, i1, reali;
+ Y% s4 X% P( e$ H  J& M3 [: X        if (lenA % 2 == 1)
" ^% E  _9 t# K: W  @4 }3 F                reali = lenA + 1;
' ?; U& m  {5 g% o/ ?$ U# j        else
) R8 `  ?7 |9 n% A                reali = lenA;: ]; M8 w8 g* }6 q* U5 b- g* l8 I
        reali /= 2;6 f3 Q& |/ q  z0 ~0 B# `

+ P5 ~, x7 ~0 F; t) z+ U& [( A        int nconv = reali + lenB;
2 i- N4 k" r3 M" h) P+ e        //#pragma omp parallel for8 n. c0 C+ j* F& v
        for (i = reali; i < nconv; i++)6 G1 R) h' ~* d, R% l. [1 B+ u& G
        {2 L# l" p( Y+ ^# e5 ]2 U
                temp.re = 0;4 b  C4 T, j5 ^; q8 ~1 Y
                temp.im = 0;
* h' k; z4 a, J4 o8 m                i1 = i;% K$ i  h9 T' z8 t
                for (j = j0; j >= 0; j--)6 y6 D" E/ x1 W: M* W
                {
; ?+ Y9 `$ m. O3 P                        /* floating date operation */7 q7 {. z; n% B1 H! ^
                }
' f- V: q7 ~  E
        }
2 Z  F: v7 E5 R/ }, J}
! h, i3 J1 ?$ x9 f/ z: g, k( \3 ?- @- T
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样6 `9 ]! D$ P5 h5 \: w" v1 K

4 e" d1 [: y# y  W$ O' F红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
$ S) Y4 y4 Z7 R$ h' Z7 L$ l现在call xcorr 100次,耗时78s.
( Z0 t# u8 T0 m- h8 ]$ M% D! {% p8 ?$ T6 g9 t& U& A, {
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. + e2 Y) C2 z3 u9 A

; d6 H' j! U$ ?# M" Z
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33% @  m' Z# d( h$ ^. l
Maybe Debug mode?

( H! {: P1 E+ W0 y& K# o5 ^% G* d; C! x. c, `( D
不应该,看我上面的回复。
! r  f- B7 e& \0 q: E+ e* M% Z$ S8 c. a
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 , \+ @2 K5 ]0 d- W2 c
雷达 发表于 2022-9-24 23:54
. S8 Q$ {. L' _; [. P4 gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)  c: N" p; o1 g6 s
{
2 s1 i, _6 n  e0 M        comp temp, xtimesy;
" `$ l/ }' g4 c7 ~, N+ O
- X- p1 h- k, u2 M  Q& W
这个不是这么比的吧。。。6 ?. G" x5 o* p! q% h( c# r

* k# ?" O( x( x9 S* z您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。, _, d5 [) b3 M$ C2 K& ]

; r9 h6 ?7 u% i# x$ {; _' w而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 1 O4 d" ^7 h! O3 D3 M# Y' I
数值分析 发表于 2022-9-25 00:20
& O6 U# R1 H) Y# G0 C; g这个不是这么比的吧。。。4 \# J. Y2 t% q

* ?' r" g7 p5 ~+ i; v您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

* ]1 r  ?4 Z5 t/ y' E/ d. Y4 J1 S% E( Y2 [, I4 \* K
有道理。; d8 ]: ~8 F$ X: k. U! {
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
: y# d3 Q  r, o* j$ l; T6 H
: R& w+ P" y& [* ^8 r我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46" n* L- r+ e% q) J/ h% ?4 F
有道理。, N: n$ Z+ @- Z9 W4 Z( Q
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
( j1 p0 Y$ b9 o
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
( |' {' U+ L) T3 v7 lWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
$ O7 i7 T9 Z7 S/ {' c1 _这个不是这么比的吧。。。3 C2 M* P* a3 E6 ~2 x
# M9 D# z1 P/ f& G( L3 f: T
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
7 d/ \6 ]( C& S
4 S4 J1 d7 b- ~& L! X
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
6 H  Z3 v0 B$ a& ^4 F8 `, |9 P$ I5 p
沉宝 发表于 2022-9-25 01:48+ _- t/ c  v$ ^2 ~9 u
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

9 L2 g6 E" U. y+ u; O! U  d" c8 N$ d" r/ Y! b# @1 k& r
是的,兄台说的对。
' C  }; Q0 q. D
& S% p1 R1 v, F$ E! G$ E! @+ D其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
, \+ S  W# t4 P! c8 D0 T
  h8 L) p/ z  Q/ J* c/ e% g0 ]雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。' u4 L: ~1 X+ }: A  d8 d

2 F4 V8 W2 D. C- ?比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
4 N6 r6 \; G/ ?
6 i; m1 q5 ?3 Y! ~: [. ?当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
( y  i4 D. i& u5 _+ l
沉宝 发表于 2022-9-25 01:27
$ R$ A( j$ ?9 b# y, h你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
9 m2 v3 u4 G$ `6 j: _2 B+ M" R

& `% |- s2 `) O1 K又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
9 {' G" w$ ?& P  L
  K. r7 L; p2 W6 t$ `# d我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
( M5 X. i2 J& j又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
8 i8 R+ B6 ^8 a+ \0 X; N
时间差一倍的结果可以接受。
. o: Z, j' d; H* F) W5 t& z+ v! U, m: k+ k
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
7 B3 W6 ?  Q; o) o4 N. d6 a
雷达 发表于 2022-9-25 04:47
6 c/ [  U- V6 F9 O- N9 Q- X又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
* |, H: s/ a* |. {$ e
3 B9 `; x/ o, r; X* V+ ~/ }
6 V) D) @; [0 @$ X6 @

7 Y+ e4 v2 U% _7 u/ V能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 * j# D. x+ R. t: H1 C( _- n
数值分析 发表于 2022-9-25 14:58$ N5 C: I$ S6 ]* V
能不能把这个也贴上来,看看和上一个有什么不同?
1 {' f/ T. ]" j) e" R
理了理思路,重新做了一个测试。
" b6 w. ]0 i- [; _% X7 y/ a做了两个 vector 和 两个 float *, 都长 100000
0 ?. f- m5 {+ q4 F. I, W& I外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.) |- d& v" q" k

' ?" Z# a- d/ a) r" x& M内循环试了4种方法,8 W# r- e, O! T1 V0 w6 D
1. 直接调用 vector inner_product 247s
! F* V9 e' r  H$ y& G+ ?+ z- E, [2. vector 循环点乘累加 237s
1 \& ^& {/ ^0 O# i8 R" {& G3. float * 循环点乘累加 204s
/ n6 N# V" }, B  f3 u' H" Q4. 空循环 100000 次 202s8 t9 d: _! D$ X+ h+ U% y" U3 E

/ d" r6 w& J& D/ P6 K2 {9 z不做内循环 200s
2 E4 @' z& u3 B" g
4 Q1 p7 g8 J8 F7 q* \+ X你昨天说的对,内循环本身占比是很小的,大头在其他处理。' V# V5 k, W$ I! `2 M
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
9 T/ w9 b% H2 U% ~8 G3 r  t9 j
( K7 W, |6 m/ ]/ `& k" N# l至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)& i  c. s# w; Y2 f0 Z
7 w6 c. A, Z! i6 W/ ~* g) \& t4 V6 ]" F
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
  |5 p" `% X! W- d% |
5 e, m' Y  p0 j. j
        std::vector < float > vec1(N);, n% R2 B! L* M  J: z- o: h
        std::vector < float > vec2(N);
! u1 g2 z' P7 l        float* b1 = new float[N];
6 U/ u7 u8 |) k' S        float* b2 = new float[N];( D8 x9 u% C: g5 ^) L* m! I* R
  j  q1 z) E2 j) Y# s. d& t2 V
        for (int j = 0; j < 6000; j++)7 M, K5 `* z) H  a5 N, r
        {& g- i5 L' T# h  z7 q/ c' p2 t
                std::generate(vec1.begin(), vec1.end(), []() {2 m' B% d6 g2 e$ j
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
, K  r4 k3 O1 V  v4 j) K- Y                        });1 v$ i; |) T' V" ?9 n5 C% [+ m

+ b4 [- Z& d6 z# Z                std::generate(vec2.begin(), vec2.end(), []() {
. Q- W4 ]# G4 A" Q                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;# H0 w  i* l: w8 \7 u4 o
                        });6 i# ?+ s  ?" e1 p# i

, G' o/ d/ {; t7 o, Q5 m                for (size_t jj = 0; jj < vec1.size(); jj++)
+ H' N. z% a" P$ Y$ v7 i9 ]                {
8 y% d: ~( t& N& `, W" x                        b1[jj] = vec1[jj];* T0 f9 v; e; R( p, s
                }$ X4 _: v0 x, d4 l% c" c
. w( C2 T" `6 @) W/ a. Z
                for (size_t jj = 0; jj < vec2.size(); jj++)
# D' l4 Q" h6 K2 p2 k: K4 N: C: U: J                {. [" ~5 b$ ^) S) E
                        b2[jj] = vec2[jj];- e4 l& {7 G' M/ n+ F+ B+ A
                }
0 L  o$ u: h, v+ e, a9 c0 t$ W: I+ }$ u' X# A. _0 f7 W' _
                //Method - 1  N=100000 247s  ( b# M5 e$ H3 d: n
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);* o) K) M! B$ S
                                
1 q( J& h0 I  _                //Method - 2  N=100000  237s( h. X: E2 q( `/ E# i4 \
                /*
" S3 L7 T1 D, _. A6 R1 A                for (int jj = 0; jj < N ; jj++)6 Y1 p. v2 q: h* c$ x/ |# P4 l6 X
                {
0 a* `5 c1 L" K& c& p+ I' ]                        fresult += vec1[jj] * vec2[jj];# m' c' h: F; h4 m- D7 s$ S
                }
7 c' d( U  |" T" w2 r# Q1 ^                */
0 a- a' q4 R. Z                                : F. C% y2 f( Q" E( h7 H) o0 r
                //Method - 3  N=100000 204s0 J& ]5 j2 L& y5 O! j3 z
                /*
% `$ S% v+ D# M8 z) z6 d3 {                for (int jj = 0; jj < N; jj++)- x5 V5 [! O; H; A5 M. F
                {) j7 {0 m- ]. z( R1 m$ `- u+ x' {
                        fresult += b1[jj] * b2[jj];0 P% ?6 F: Q( i. w/ c) C0 e+ ~& h! @
                }
: }$ u- x0 p# X2 e4 i6 Z1 h                */  Z/ @" }0 S5 _

" o% A7 ]5 ?9 A" a2 ?! p0 z+ e                //Method - 4   202s
) q4 ~; Z/ }% g" S$ @# V                /*) X8 q' h3 T6 `# [1 a0 H( j  H
                for (int jj = 0; jj < N; jj++)
( p. x' h- f6 X7 l+ s+ t                {
* Z/ c5 r7 V7 Y3 r5 E                        
! O" l/ s# l% N# t, Q9 Z3 v, U                }" @& v! t2 h8 r, r0 z& \! ]. V
                */
- l( T$ ?8 a0 b2 m/ N1 E                //comment out all methods, N=100000  202s               
7 n& n/ [) k  f2 a, A+ k        }
& A: t6 b, ^2 c9 a0 S' u$ }
3 y/ F& ^2 `! A/ ]7 _/ i        delete []b1;% l! _0 n; p' h, r" u. S( B) v% Q# W
        delete []b2;

# q* V6 R( X6 `& y
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?4 k( c- Z, p( {, q

- M7 G7 F" L; b0 P" J你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?! V; J3 @/ ]8 ]% I% t8 h

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
$ f5 e6 ]- ^0 A$ Q' w瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
$ u7 H: o! _. }
% F+ y% J1 ?5 T# h你第二个试验里面的j在循环里面又重新定义 ...
0 U6 A1 }: g) p* w" W4 c4 ^( W
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
+ V( H$ `% z" |! ~4 k6 \. _
  {7 G( ]9 n, P" ^不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:168 u6 v3 f1 O: v
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
1 X" ^$ }: D) ]  X$ L5 M) ?1 Z# z7 g
不和它 ...

, P0 S7 i1 ?4 b" J5 U
  S. C9 }3 d- i  L1 J! ]5 g不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
2 e# D# e, H! B" c6 [; a9 R后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54( _# d  L8 |) @$ k
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)2 s7 K8 s& K; W+ Z
{
+ W& [8 }- e; [4 P1 t& C( C+ f        comp temp, xtimesy;

1 h- k2 [  G  h8 r0 M0 x. }这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
+ x) c$ `2 ]! ]# L5 W$ q* L4 w内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
: M5 Q* F" H1 i& mVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30) J" v8 ~; S' [* z
理了理思路,重新做了一个测试。! G3 i: Q) d- I/ x+ M7 \$ ~; f
做了两个 vector 和 两个 float *, 都长 100000
/ {& B2 Z- v. h0 k外循环 6000,里面先做随 ...

4 ?( E; _/ [" b1 n1 R( A$ r; e7 I这个时间是从哪里开始算的?* x9 e( b7 l2 G6 a, R4 a
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
2 {$ {5 A0 Y- A按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39  |; J0 E' \* o7 ~4 Q3 O3 I
这个时间是从哪里开始算的?  Q+ y; B0 Q/ X# ~
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
4 `/ d3 {' M" Y( n0 b* R
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。; t3 {; J( ?+ n: k
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。5 o* n5 L9 K3 C( x6 P
与此对应用数组(指针)花了2S
  {( Y/ ]( M* @- m  v, }0 C你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54  v& U/ U+ o  e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ U. o% {6 ?# q2 S& O. W. p{; L# `8 l/ u: U/ ^9 [8 z/ G
        comp temp, xtimesy;
, c* l. Y* C( Z  C  S
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
1 q! ~% k+ i/ }& M+ G
. C2 @7 \1 Z" G# S
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
; @( G' v; @' _% H我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
5 O* c5 |4 F* s0 M$ Q+ B5 I5 A* L: R( E# c5 f4 K( _
...

7 b( L2 c7 Q% A! z你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。2 Q* c' c% Y9 N

7 w2 E8 v" n: U, e  V/ V雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
2 f# d0 a  y) Y
3 k2 ?" p5 i; c是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
: X1 I' W; u. A" O+ P5 Y1 |有空时我会试试 SIMD和并行,看看能提高多少。- J# T; M, r4 ^* f+ m; x1 W- J
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 1 R6 f8 S# \# }1 |
谢谢大家的讨论,I learded a lot.  红包已发  
2 r1 w. e/ A' ?6 |& w/ {; A
* o/ e2 C9 n  z# J8 L) [1 E8 ~3 F' `; j) f3 E: S6 F
( J9 V1 c. g* h1 @  n* C( {5 |$ g8 v

$ Z" e# C8 O: k; N, e




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