爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
6 z4 S) d( x: s: }  O# t/ G: J7 D
# M/ }. _2 o& m; n' c9 e自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
- a# W3 S, X$ V/ L/ J) r# O, ?1 S4 `( n. h) Y, U# a" A
速度优化问题真的很有意思啊。2 d# y; [: `7 U4 m2 Y
% T. ~" G0 H% ?5 x
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
( E8 j" [8 ?; r5 i- ~* N: d3 i  ?4 L把代码贴上来看看?3 r% h1 o: Q; L; ~

6 c. L- @0 @* E& |, }  z难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
8 |' ], z2 o3 D- ~* z9 q
数值分析 发表于 2022-9-24 23:04( y$ t  X/ A+ j$ w1 {3 i
拉下来?拉多少?, Z3 ~3 K+ B5 _1 T/ Q
把代码贴上来看看?

/ L. a% x8 v$ Y6 G  O7 U$ y: n) m/ @7 P
7 I& ~$ t& p# g. uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  b" u% Q/ D: s{- G7 i4 [! {8 x& u; S3 I
        comp temp, xtimesy;! L& K& y; N% z! k' Y# s
        xtimesy.re = 0;
' E7 f- [& J/ f        xtimesy.im = 0;9 O; r5 F* ^1 P- k7 Q# }
        int j0 = lenB - 1;* ?% X  z* W5 E$ z
        int    i, j, i1, reali;
; Z5 p$ U3 \3 X# o, \        if (lenA % 2 == 1)
6 m( X5 G+ q7 A: ~) P                reali = lenA + 1;+ O% ^! R) c( s, j/ ^
        else
8 R: T2 a4 ?; V% e3 h. s! M                reali = lenA;
8 z  l( m0 J$ b# ^! {5 C# a        reali /= 2;$ ?* n) ]% q( O6 O
( J- Q* \8 Y0 P" ^3 }
        int nconv = reali + lenB;
$ V2 u+ a2 _. I! _+ G& g! }        //#pragma omp parallel for
5 E% v6 l2 q5 o0 x8 {* R, U3 y, P        for (i = reali; i < nconv; i++)& n; k! T5 X7 Y8 @* y; F# H0 N
        {
& z" [, n9 f$ D! h                temp.re = 0;; I* o5 n% F) Z
                temp.im = 0;4 G, T% K6 ]# ]! r8 e; t! `3 o
                i1 = i;
; x* l# `7 ~7 G( Z7 E( e! ^                for (j = j0; j >= 0; j--)
2 Q, I* h2 [8 m' r                {
- X0 I% r$ e4 E6 g# {( `                        /* floating date operation */
: }, H2 ^- ~: Y' T                }
  j* H0 |) b# ], R
        }
) q& n- U, T$ Z: b, t! U* F}5 ~" y9 i8 T/ e, y2 e
% i* z  j+ u/ ?, W" ]4 L
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样3 {9 r+ `) `/ S' e/ U/ q: e
9 |, p) J& }6 [6 m2 C- l
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
- t+ L0 C& Q! y! k" O6 W* `" z3 ?+ m- Z现在call xcorr 100次,耗时78s.
. T3 b) I' _) P1 V) V$ z# M  {- n. z! {; @% D/ h+ w6 `; a
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
: I) m4 \+ j4 r, \) ^: q+ S# C; a: ]

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
, v) |/ F7 d3 K2 N6 @( f) k7 UMaybe Debug mode?

" e% m, l, z1 w8 \: z# {' h" [- B
% _+ i, _+ [- B不应该,看我上面的回复。
- s2 v/ Z& z) U2 ^. I6 k( y. D# W
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
0 |* y# C9 n% V& x! R% @* F, N* W% w
雷达 发表于 2022-9-24 23:54
; ]# I* @* z5 j, P6 T- @, I2 nvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) I$ }: H0 D# ~! T- ?
{( M! v' N' F9 Y1 s' ?, f& C
        comp temp, xtimesy;

* i  M5 @4 c. B; p" P( c) F
# x/ M: {" x* Y6 n7 X0 w8 h这个不是这么比的吧。。。0 o) O0 r* v! E
4 C3 w: f& }1 t9 G( `2 }
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
; U6 \) d& R; |  Y! T9 M/ g- `4 J+ ^2 z5 t
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
9 `( U0 _! F! @9 r; f
数值分析 发表于 2022-9-25 00:20
9 F$ X" p# F% q4 k" n. b  Q这个不是这么比的吧。。。
) Q* C8 \+ `2 `7 P$ l$ q8 n
  U( v2 [# Y9 s  e您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
% b8 v7 z! U  X& h) R% @

& U2 O( e  R& O5 t0 T" d  ^* f, E; K有道理。
1 z; t1 ^& t' X( C5 W9 W# v所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
7 U2 ^! u1 i' V& b6 d. T: n1 U4 e; O; e; `5 |8 a
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
/ t. h4 E" ]( \1 P有道理。% K6 A! x8 }  G% K$ x
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

+ t0 s$ }1 B2 g( B4 X你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多0 ~1 M+ g- U, g7 S7 A/ l
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
# A2 f6 b# D7 t& {3 m! }2 Z# T! q0 \这个不是这么比的吧。。。
  i; \6 k: D9 q8 j4 \9 ^( j4 o" l# L
" F8 O' ?* T( C; l! O& a您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

* c* ^, O7 d6 S
1 i4 ~: K3 b, C( g! F" m现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
( W/ _0 d) e8 S0 r+ y/ m
沉宝 发表于 2022-9-25 01:486 W( y1 `( U$ N9 b0 [; ~6 n
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

) |& L5 D% s. D* S! Q( {
* L, e: j! k# }8 q2 l: m是的,兄台说的对。5 w" U+ E2 r2 ^. g

( c* g& T/ |: z8 c其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
+ W) `0 [3 N2 s0 [
/ D& G% Y8 {" G; X3 c: k雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
9 M  ]: |( \' R. p7 ^8 z5 J- |) I3 u  ^  X/ {* v
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
1 x8 F  [; [1 m( o! y* V" }6 J5 X: S( s0 l2 x6 q% L
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
2 q* H, Y0 X  |6 _2 A+ j
沉宝 发表于 2022-9-25 01:27: A% X. C9 z2 s$ @, Q% p' S1 Q5 P7 y' z
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
8 u2 r4 v9 p3 ~- {6 i

7 l& m9 v) T- I) P又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
# w7 y% r1 {$ t! k6 g! e2 y; @6 v- ]% Z+ p7 Q9 F9 }  q" r, o* X
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
- U) |* `! i) S% y又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

( i, u. K7 g  x% X时间差一倍的结果可以接受。; `2 U, I! m# l7 s' w- b
6 S% A$ L  F! v4 a3 M8 p
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
: b; i+ K: i! X$ j- S
雷达 发表于 2022-9-25 04:47
) o  `$ l9 C; k9 F, r# u/ a, V# z7 e又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

' Y, K# G: x3 {2 t; d7 y
5 S2 o* Q, [/ W/ I: g" c, y; |8 e4 @* ^. z8 S
! e* R* \  ?& n  F8 E# C0 F+ w' ]6 B
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
. t# N3 D& z( [; k5 \# t& @
数值分析 发表于 2022-9-25 14:58
3 R7 L) g8 r! I( l能不能把这个也贴上来,看看和上一个有什么不同?
8 v4 v0 i  f! K: E( P2 V
理了理思路,重新做了一个测试。' g- r) P8 L. C2 s6 V0 m
做了两个 vector 和 两个 float *, 都长 1000007 S! W+ R6 L& D
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
' f7 Q6 k  |" w# H- q4 J3 V4 J
! S( j, C+ h: d! ~: b内循环试了4种方法,
2 ~5 l0 M5 `$ \, S+ p1. 直接调用 vector inner_product 247s
+ e; S0 T3 Z4 l2 w2. vector 循环点乘累加 237s  J& u: @" n( Q( H1 Q% D' B
3. float * 循环点乘累加 204s
; f& q7 t, e2 f) h8 _4. 空循环 100000 次 202s4 c" V1 X' G3 l1 h6 F& h

, @: f2 ?+ [3 s5 _1 ^' z5 f  H不做内循环 200s5 Q6 X# A% l# w( T

, P* l' O" Y: l& a' P8 O6 ?% A, i你昨天说的对,内循环本身占比是很小的,大头在其他处理。
0 ^: t# H' C% A" y# l0 l9 L另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
8 O% B. R' m) K2 U/ j! N! \; W. k2 v3 s) C7 w: [% U: p
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 f3 h, t& b$ ]1 @3 h8 h
: a* |+ m, ^+ n3 `$ P6 z2 e0 h! U8 f
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)8 w3 R  Z% M2 O! n6 ^- b

/ ?) N- x0 F+ R- Y7 b$ h
        std::vector < float > vec1(N);  M6 F3 e8 S9 S! O6 A6 X3 u- u
        std::vector < float > vec2(N);
1 a2 m: O) t0 i% p- M! y- G        float* b1 = new float[N];) S& ?2 L$ m' \. p' l9 m' J
        float* b2 = new float[N];
4 S. R1 ~, a' I, L, Y4 ]: y5 }  D3 `, Y/ N: }1 s1 w) b8 L
        for (int j = 0; j < 6000; j++)
4 d( q9 S/ w' u8 D        {
) H, r' r+ i: S% ^                std::generate(vec1.begin(), vec1.end(), []() {! c" V6 g# M" ?* }5 H8 ~
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
1 U7 d# R+ y* V- d' c                        });
6 D6 k2 S: _  J9 m0 a! f3 _! Q- S$ L' ?: L4 h' M
                std::generate(vec2.begin(), vec2.end(), []() {
( [& Y  F/ b( Q, g  b                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
7 Z3 O( M: m3 n  J! w9 Y# ?                        });
8 r( X1 M, c  I6 a4 U( k1 D4 X1 t, C  F; K* D  z9 x
                for (size_t jj = 0; jj < vec1.size(); jj++)
' X$ g& Q* n8 M                {
2 U5 [2 C: Y! p+ ?1 N' W2 l                        b1[jj] = vec1[jj];
+ g* ^, n' _' _" z, B  H                }
7 B- A- x0 \- n  F6 L2 {2 }. |7 k; R* I" A; J, B
                for (size_t jj = 0; jj < vec2.size(); jj++)
5 K" T5 }7 ?, p6 C                {/ V* S: ]5 V; h! ?) K
                        b2[jj] = vec2[jj];
- |! y2 L* }; t; s  A% ^; n                }6 ~% w+ i$ v) j5 x. |
, `9 a/ q0 a6 V) d  ]# z. B
                //Method - 1  N=100000 247s  " z  b+ u# k& X1 C
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
- V- [* b. n1 g& D% J4 j8 Z                                2 H3 }/ _% K+ I
                //Method - 2  N=100000  237s
" f6 ^9 `5 G5 ]+ P' r                /*1 h+ |" g; d7 U
                for (int jj = 0; jj < N ; jj++)" x2 g0 ~. y+ L% E" P
                {
# a; a4 Q/ S- `" _' [2 F: a) e                        fresult += vec1[jj] * vec2[jj];, t' ?& t7 C% `- D" f
                }8 N0 o( b5 x) U' |/ c
                */9 Q" m1 g: v$ c( M  x
                                9 ~0 L" y/ c( m5 l+ D; F& S" N
                //Method - 3  N=100000 204s
( c2 \! Q; ~( J; \' z$ f                /*
$ U# Z! O( {8 O: L! j                for (int jj = 0; jj < N; jj++)
0 T2 F' q; ~$ a( b# I" i                {* n! z  ?+ |; \8 h0 g
                        fresult += b1[jj] * b2[jj];( V5 `3 z* Q; ]
                }
0 _) [, Z- I! \& D; l$ G  h' k) W                */0 W! w% j8 ?% n1 _

: w4 {7 Y" d; a; p* g: s; j                //Method - 4   202s
2 b( }% D1 I$ X  T4 P                /*5 N# y9 a3 X! ?& ~9 `8 G1 ?: Z
                for (int jj = 0; jj < N; jj++)2 a0 S! r. v# P* ]) r9 j7 v  L
                {7 O1 z, [, o% M
                        * q9 o8 ]  S( w- P/ L
                }/ p+ D. k, n8 n, b# q
                */5 K7 w6 |9 {) n  h. d
                //comment out all methods, N=100000  202s               
) x2 s/ I3 @, d3 B: ?7 ^        }
# |! Q; h7 B* u/ e
6 F5 I& v3 O" d+ |        delete []b1;: W5 W9 U9 N) Z% U
        delete []b2;

& S% s$ t+ c. }
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
8 f8 B  u+ T5 l, S, w/ g" i+ _/ {- ]. ~6 @9 c. P/ L8 B9 L
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
" {  {! \9 \$ p! V( w
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
) l# ^2 T; s0 \瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
# l( o3 W4 I' J  v- \
4 b1 ^) V  m" p0 `. e你第二个试验里面的j在循环里面又重新定义 ...
7 a1 ~' O; C6 K* g4 [
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL; G8 [9 Q. l% }( g- G" T
  Z) U% Z% j9 k, N& r- [
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16  U- N5 ~& |( d. A& Z% r: L% ?/ ]: g
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. G. u' J* u% G0 O: Q* b
$ a6 ~' `+ R' }, C* o
不和它 ...

+ s: Q! g/ w0 S3 E8 s( H% {
$ ^8 y2 x- x/ N- ?2 T! H不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。3 G+ }1 ~$ s4 o' x+ W$ s" o
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54+ o4 x0 s( @7 C7 Y6 d/ n- I
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
! V$ L5 m  G! K2 Q0 r{6 S  }$ |: o2 |: Y: p! q  _( y8 e  }. S
        comp temp, xtimesy;

- _7 |  {0 B3 f$ P( z这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
! B+ x8 E1 m- s7 c: ^  f3 h内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
- E& I" W, m: z+ WVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:308 X: {/ o3 V. |7 }6 }/ F8 }
理了理思路,重新做了一个测试。2 `/ x' Z2 k/ z6 F/ |, T- w
做了两个 vector 和 两个 float *, 都长 100000
6 ]/ t. l! G% m5 A2 M外循环 6000,里面先做随 ...

1 {" p! d' @3 J9 S- o' H$ o! Y+ W' u这个时间是从哪里开始算的?3 S8 Z; [. B0 I
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
% b. X2 A5 D" }' ?: p, @* Y3 }8 {按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
9 b8 [0 b0 ^( Q; ?) h! o) u这个时间是从哪里开始算的?+ f8 v- e" S7 E" ?: n: s. L
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& e& p  U+ e" n$ S6 R8 I4 \
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
0 i8 S- Q/ E6 f! [( r. K3 y  @+ S: Y你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。6 h$ H9 g, R% B$ D
与此对应用数组(指针)花了2S5 U# T9 i# \0 y
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:542 E/ i' G; N5 a$ k9 w
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)0 @$ k" h  |: R. D! y3 x* A
{
3 c1 R4 t+ u# C9 ^/ }6 a        comp temp, xtimesy;
# r2 O2 b4 V+ R8 W' Z  L
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
1 u( @0 _9 c& M& b' O
1 r1 k4 l, |" j+ T
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29) ~2 X( r8 w& j: w3 [" m
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗( x0 D- |7 L+ m
8 m4 s4 @' z1 e* a8 ~4 S5 I7 N& Z3 e
...
! n3 x. L6 Z0 m' v8 \) `2 Q
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。8 w! ^0 u* ?$ }# t
& }/ b5 d9 q3 }5 B' J9 y: [
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ' B6 w2 f& o/ B% [3 v3 m% P) J
& V( ]9 z) e: p6 R9 R
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。4 d- b- L( o; n+ ~
有空时我会试试 SIMD和并行,看看能提高多少。
& X# B: }, r; b过去7、8 年没有正经用C++ 写过东西,没有 sense 了
/ W/ ^/ O9 C$ Y6 G( b谢谢大家的讨论,I learded a lot.  红包已发  3 s' K4 A8 X! x3 P
: U0 `% x! W( E

3 _9 I2 o$ P2 U) M: `: n
% N5 k8 }2 v1 M9 M
- g. z4 ~/ o* ^: l1 t




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