爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?* Y$ i/ a  C9 O) O% O3 G! }

; e" @3 p( {( P4 O" g  ~! J; o自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
1 G) ^- ^- h9 ?  P8 w- t- v6 j5 V' N- R; F
速度优化问题真的很有意思啊。/ v  s- H7 v$ \7 o/ Z" |* u
4 G8 j! @! d+ J5 T$ |1 Z
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?% D  v! p7 h0 [, B9 e& G: h1 n7 ~
把代码贴上来看看?& s1 a2 ~- W0 [) h

4 f' c- g/ b  h! X( j2 n2 b8 |难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
/ n! G, J$ u8 P+ G4 S9 d) B
数值分析 发表于 2022-9-24 23:04
& c( A) A% [* G( \$ u, d% G拉下来?拉多少?
6 N3 L# d3 l( G. p5 @1 s3 K把代码贴上来看看?

( \5 w# Y" u8 ]8 U$ e
4 ^; ]# K2 g( g) g- h& J$ Mvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
" x& g1 ^) A% O: V8 n{
/ {" ]1 c% v1 h4 l        comp temp, xtimesy;
2 V/ r: b2 D4 @5 m0 L' s9 h& E        xtimesy.re = 0;% T/ Y' H! T- H# k2 V8 H
        xtimesy.im = 0;; g8 Y3 ]# Q& T
        int j0 = lenB - 1;5 C& I" U' Q; C& d) O
        int    i, j, i1, reali;2 c* Q6 R; t' t0 g
        if (lenA % 2 == 1)
2 x9 d/ d" }+ s8 F/ e1 k3 \                reali = lenA + 1;7 ^, w! ~* H  \: M# v" r* c
        else3 l0 F( U2 q8 `' l: A+ c+ }
                reali = lenA;& C6 j) d+ e/ I$ X. U" e/ [
        reali /= 2;5 N5 Y+ E) R6 z2 C" P

" D8 ~. y& @) r# m" \6 n/ t0 E( r        int nconv = reali + lenB;5 V( n; d  n. }: e+ f
        //#pragma omp parallel for
/ t  ^5 Y- z6 S& E, |0 ~! Q8 r6 }        for (i = reali; i < nconv; i++)2 J9 R: V8 I  K( h* F, ^8 @( Z
        {( C( w" ?8 }6 {5 T$ {- r% Z
                temp.re = 0;0 y) f) Y9 p; s2 I
                temp.im = 0;
' R' e+ [# g; o3 V6 k& f$ x! D0 w                i1 = i;# x+ V# C* h" R7 L: H
                for (j = j0; j >= 0; j--)
( ]5 M/ n2 t, u1 X4 M. y8 q& ~0 E! n4 F                {# i0 `+ \- I3 u7 k" F( F( Z
                        /* floating date operation */( o3 }1 ^/ ^. `/ b9 p/ V7 w0 x' R% ^
                }

; h$ R9 B6 L2 x& S! {        }
/ H" N. Q) ?& q9 ^$ |}
8 F$ z$ j7 ~6 B6 a
6 R1 g  j2 D! R3 Q8 ~xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样. Q9 P( h8 k, y6 p& h( G! M5 R

7 k9 e2 F+ \% W, I; m红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
  z) O+ `8 O9 Q% `1 N; n5 j现在call xcorr 100次,耗时78s.
2 E' d( B# x5 y1 X* |2 S9 n1 ~" ~' U
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 3 K. n3 X! u; O, _  g, ^: x+ w
! ^9 T, g. m9 X; n, L

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
4 N6 O  W. L. T' W/ t1 d( m: _Maybe Debug mode?

" W; e! v& X5 A7 a( b! P' [4 [/ s- x
不应该,看我上面的回复。
( \3 B/ D7 U& U5 _% T$ e; S2 m' [* B% m6 y8 P: ?4 E- R2 _
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 0 Z! _3 m# J/ m; o8 F) s2 O" d8 `
雷达 发表于 2022-9-24 23:54, s4 S% Q: @: w0 n2 Q) p5 m+ a4 W  @& o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
6 ]0 p/ ?' V8 `: S0 g{# g1 j% R# h1 z
        comp temp, xtimesy;
) l$ f  r4 q, l- o' |$ |6 A

2 g) i5 E# n5 Y8 @+ U4 s; U这个不是这么比的吧。。。: C, R7 M& h6 x- w9 @( k& A( [

- K4 V: {( j$ A2 p4 l您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 p+ i5 K$ y$ h# N0 |
/ c3 k/ b* k& ]6 H$ h& _5 i而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 % k5 ?" T4 r9 |  M* N7 ^  F
数值分析 发表于 2022-9-25 00:20. K  o" |* ]/ U) l1 o1 S/ G% v
这个不是这么比的吧。。。3 f# J  w' S+ k( a# [
" t4 H" j8 X7 b1 r: {1 T6 N
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
) W9 {! {) ]! ^' ~- `2 _8 a
/ a2 Z' @$ A1 ?9 v1 n% ?' g
有道理。' y: Y) i" ~* B( R$ [
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。& X4 O$ _) o$ k; ^7 F* }9 t

' x: c; L* R( b# C我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
8 D. ~7 Y' j! I: i" b有道理。; v8 c) x3 G; I0 B% A; g/ ]4 \
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

, {' M: s( _) |2 S7 x; t. H你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
* s: Z( h$ g7 z1 e! v, JWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20# ^! v. |+ B# O* m5 \6 j. S0 l
这个不是这么比的吧。。。
. p1 I/ K/ ~5 E* d) l% u+ W
! X# M9 {4 R$ R4 e! K9 l8 n您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
3 V! K" C7 s3 ^$ R5 B

0 s( K5 t" Q, @; f: t  p  ~现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
, P% e& k6 R0 ?4 `4 W: F! }
沉宝 发表于 2022-9-25 01:48
1 m& M  B' {' g2 @! q/ M- T现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
6 |* W1 d$ n; O* [9 }# B& H

4 n# O7 Y/ T: e9 i2 b, d# z5 |是的,兄台说的对。
3 T5 F5 w) L$ u; d! W7 b8 {) P1 \" O8 A0 D# t+ I
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
0 _7 ]; Z$ B5 e$ j9 Y& B( ^6 ], y+ K5 l- i2 A) L  c
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。/ _" X. V! _, \5 b7 f9 H8 c( o
) O$ a+ M# K7 O: v2 P9 x
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。6 [2 R9 D8 b( I: _4 W
, F4 e4 J+ r7 E3 p% p
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 7 A. v5 F: X: ?( I
沉宝 发表于 2022-9-25 01:27
+ q/ ]" L9 G! A: O7 e) u  |你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
5 K6 t+ j4 ?  N- _! ]

8 ?& V" g5 m& V& b; l又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
, g9 X: {6 }( o$ ~% n/ D! x7 P( V/ N9 J2 [' I
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47  F; T: u/ a  f, U. t( _
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
3 g. [( S" \  E* Y( I
时间差一倍的结果可以接受。
  A0 ]/ V8 j4 ~4 D% S4 N
  c5 U8 \5 X3 y0 y& c你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
! D6 \- |) V: R- T
雷达 发表于 2022-9-25 04:479 e$ b: L% B" M0 Y" Y0 D' c
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

; g. y" J9 g6 X( R
- Y9 N( r! B, g7 s" Y6 K/ O. I
- k  T) g# V: T! K! t( U- l( R
+ F; s& M6 v7 O$ h( }" v: _% p能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
& l/ d* Y7 y, l5 [, U
数值分析 发表于 2022-9-25 14:58! ?9 l# V2 J7 \) b: ~* g
能不能把这个也贴上来,看看和上一个有什么不同?
* A5 E' |4 k% N/ k9 H0 T, U
理了理思路,重新做了一个测试。
0 x5 U% r' k* C& o9 Z2 k# J做了两个 vector 和 两个 float *, 都长 100000% v8 u2 _# n1 }" [) L/ A/ o
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.; J& U6 A9 s' N, T( Q" k
9 z# |  q0 T6 K; _3 F' R8 p5 t  I' u# Z0 P
内循环试了4种方法,
5 z. _8 T& X8 ?8 w1. 直接调用 vector inner_product 247s
% y$ s8 |* L3 f4 f- _! m0 P2. vector 循环点乘累加 237s
7 \* o" V7 z0 {  v3. float * 循环点乘累加 204s0 R( D2 R7 o: Z- a& f2 i, X
4. 空循环 100000 次 202s
" Y$ w/ }2 j3 u% E. _
+ \# i; w4 b2 E9 U5 K0 v' B$ T3 [不做内循环 200s
9 a; _  d* O6 p6 W
: ?! G: y5 q5 l6 B: t' p! k你昨天说的对,内循环本身占比是很小的,大头在其他处理。" d8 z- j7 o: _
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。4 i4 X: s' {* k' B' ]+ }* P

' j" G' M# b6 K7 h/ t至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
. I  h3 Y, n  P( R) [, W7 z- @% }: k; x/ t( @. J
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
: u/ h( B, a9 e& T" D! }3 B- N$ h! k* ]
        std::vector < float > vec1(N);
" l4 }8 Z0 E* `7 n! ]% k1 V        std::vector < float > vec2(N);! E; {  r/ i: P  o
        float* b1 = new float[N];
( w" ?6 E  q7 {) X: m9 C        float* b2 = new float[N];! d# x* d9 {- \& d: |

& J1 V3 t/ f8 I        for (int j = 0; j < 6000; j++)$ s" b' h- ^2 T4 x" ]
        {$ `. f  W$ ?9 l3 `7 S
                std::generate(vec1.begin(), vec1.end(), []() {, s8 X& F) q7 X8 r
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
/ C( q5 Y. K) N2 H5 K* G$ |* t% O                        });  U, ~8 p) r6 Z+ X* ~- U  \$ [
$ F; o+ y" z7 i0 ^, o5 b5 ~
                std::generate(vec2.begin(), vec2.end(), []() {1 W) _) q( h% v5 Y4 I. `
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
7 S% p6 b: {6 D# U, b$ N                        });
8 f. S5 q9 z2 C9 ~- R# s6 W8 S
                for (size_t jj = 0; jj < vec1.size(); jj++)
! J5 e% l7 W0 {                {
) C/ J% _8 ]# z                        b1[jj] = vec1[jj];
7 W: g. }. ?$ S. l/ E3 Z% o; c: z                }
( a) P/ Z9 K% G7 j$ Y% m* n5 i. V) h# t4 f" _# ^! C0 g( p
                for (size_t jj = 0; jj < vec2.size(); jj++)
. w8 A! g: _2 w! Y  \                {
! J" P7 D, e+ D; J9 A) i9 Y                        b2[jj] = vec2[jj];5 s# t2 P4 r- b5 v, t$ `: |
                }
9 E7 G) ^. I0 ~4 e- V3 u8 J+ P  Z3 h' `: x8 I; Y8 _% R
                //Method - 1  N=100000 247s  
% {# @# G2 M' q. C; Y                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);9 k7 _" v: ~4 o- V# D
                                
3 A3 E+ z! W% O" N0 K                //Method - 2  N=100000  237s
, j$ d. m8 ?0 U0 g0 ~1 p                /*2 G& p1 S' }. e$ `
                for (int jj = 0; jj < N ; jj++)9 n# M( Z* E6 Z! M. ]& ~* h
                {" c1 d! d% L6 @8 T2 y
                        fresult += vec1[jj] * vec2[jj];
0 {8 Q* b/ h6 G3 w* I                }
& a4 v# H' v: I: ?; N                */
+ P* @% J8 ^. a                                " ?" @- R+ ~& p% N
                //Method - 3  N=100000 204s
+ W' L! o8 W0 K1 Q                /*
. t9 b" T3 p8 v7 f$ x4 t& y                for (int jj = 0; jj < N; jj++)
$ o. E& Z$ n- i7 n' D                {
6 P% G* J0 m! w& _$ g; f                        fresult += b1[jj] * b2[jj];' `  @& `9 y4 u* c& ?
                }
6 Y; ?  W9 s- S2 t) y                */, W5 |1 @- W0 F9 A+ [

: B7 Y; K$ Q! D6 i                //Method - 4   202s
; I% o* d8 B' ]' h* y; t                /*7 l% h# O3 @6 c
                for (int jj = 0; jj < N; jj++). d" C- _2 u9 J
                {* H9 W- G4 Z1 A1 |9 W: `
                        & d6 E" [. \# r
                }' g# {' O6 T6 g1 o3 w
                */
; D1 ~2 U9 ~: R% T( j: ~8 x' W5 k                //comment out all methods, N=100000  202s                5 T/ Z! W5 j2 J; q. W$ V* Q# K
        }3 o1 D4 j& Y" k' }$ K

6 |7 ?) q+ K, {8 i8 L        delete []b1;
" z4 |$ ?2 x! r; X: \1 [) t        delete []b2;
6 [& e% N% Q5 X) l

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?( n0 [* `) g+ H- V6 v2 G9 y
; ^' @" g2 A! Y7 E3 C3 }
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?. z7 _+ D6 j# K9 V; E- z* a

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
; j/ `& j) X( a" l9 `瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
3 Z5 t8 n' Z* |8 N' r" F, W7 R
9 \' b( W* D% Q4 y6 [) O. j$ f你第二个试验里面的j在循环里面又重新定义 ...
" w+ P2 @2 M, q: |8 p
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL! F8 N- v/ u0 i4 Z+ @
' t' G) N( d0 h& ^+ m% `
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
9 G9 b- G! M- s0 [内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) ~8 W9 p/ k. Z

$ m; @0 z* d) _5 E. k( I* o不和它 ...

2 W$ q1 w  p$ S/ N7 m3 s. \9 m: S& G) c- _+ |7 X- O( z
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。/ `2 m0 A( R$ `1 v6 e' E1 i
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
& X' B" z% i* q( m- Xvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
5 A4 D, m, m1 {' j* G5 i9 o3 R{; s, t3 ~% h6 s( k1 \
        comp temp, xtimesy;
$ E8 U- i8 i3 k9 h" h/ c
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。+ H, a  G3 e4 K0 d6 a
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
7 n5 G( g% Q( L# T! }1 }VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
; s9 t3 _2 n3 U* v: g& y理了理思路,重新做了一个测试。% ?5 P6 I1 n5 W5 `# D1 \
做了两个 vector 和 两个 float *, 都长 100000. f- W" Y% K0 ?9 J7 I- j
外循环 6000,里面先做随 ...

- s- n6 B' z0 L% G7 I3 Z, W这个时间是从哪里开始算的?
5 R# J1 B( |5 I, }* h7 Z" p我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。8 v- O# j9 S  _# \) ]- K
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:396 T7 P- f( t2 ]. W
这个时间是从哪里开始算的?! E3 N% t  P% D  Y( b3 p( z3 c" q0 k
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
% z6 f+ K: Y$ w& n. e. a
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。  [1 A+ L/ j3 t, T2 M" n+ n2 w
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
8 u" C& ^  t) t- }* u. ?2 }  T与此对应用数组(指针)花了2S
8 o5 A% M' G2 _你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
9 [5 _( @8 O" Y5 h2 hvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ Q& j9 e& S/ _* s6 t{
: s0 f' E$ T( a- C        comp temp, xtimesy;
7 a* d. y0 t5 m
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
7 D! o* P* K2 N) ~! H4 E0 [- f2 Z: l0 |  x* q! R

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29, ]& S2 W: q4 L7 L
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗1 H3 O0 a# Y  G4 U$ `% [

/ J5 _* u& A1 u. y4 Y2 n ...
" s( d& v0 f2 G' r8 l
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。3 H" @) H$ x; u
' B9 R( s% e4 S
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
6 w" A- [) F0 l. w1 K. J
( v9 P/ X" U) L& O4 ~2 ~6 K是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
. X/ \+ K% s* ^3 N4 _, _2 R" }6 h有空时我会试试 SIMD和并行,看看能提高多少。- }: h) L' G' z! ?
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 4 l( s; A. i0 M7 c# `6 |( g
谢谢大家的讨论,I learded a lot.  红包已发  ' u: |1 s7 |" |+ d8 W+ `

( b, F, T0 W! x0 L7 y  m( o/ Q5 }( A5 [5 c+ Y

: ~8 q/ o' t) v! O2 k6 m
; d8 c. Q/ ~; q" h# u




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