爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?) t  K3 z: b' b
3 |3 O. F  c2 B& a
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。6 k7 S4 y* `+ P# F% `  R7 i+ N, \

* b; T, ~9 O7 Q  ^5 h# c* u; g速度优化问题真的很有意思啊。1 g3 b) e. J. J' x

3 E  A: P2 W) u7 H欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
$ F/ @6 X$ t, r6 c$ D6 z把代码贴上来看看?
9 ^- O6 q9 \5 d/ J9 w
" v! a9 ?8 \, ~  |7 D) F6 S  C5 G难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ) A  V( t) V* m, p) W  c, `
数值分析 发表于 2022-9-24 23:04
- y: e7 U0 v+ b  e" T8 Z拉下来?拉多少?- e  m5 A: S; P6 P* v: O
把代码贴上来看看?
" M# }# k, e7 g0 F

8 x2 k+ }: V# d( K+ u: |  [" Svoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 x5 s- V7 U7 u5 W; }0 X; v
{4 W. `  i: R6 F( a" C
        comp temp, xtimesy;
6 `7 Z3 [7 K# E1 V        xtimesy.re = 0;
2 f- x$ I) w+ N0 @        xtimesy.im = 0;5 y: {# X4 y, ^: U
        int j0 = lenB - 1;2 K; m/ V4 d% }9 R8 p. Z
        int    i, j, i1, reali;& h9 O' T2 @) u( q
        if (lenA % 2 == 1)5 u8 r( z6 d/ R; O! t! c
                reali = lenA + 1;0 m  A' y& m, \, d- K4 t! i
        else$ b# S' J- z9 n; S4 T7 L  Z
                reali = lenA;
1 j. s* T6 V, n! d5 I        reali /= 2;
8 G5 Z3 f8 b  _5 {8 {& j' w0 I9 T4 `+ y% P0 V' N  c& v- v
        int nconv = reali + lenB;
6 ~/ B3 W/ O% Q) D" `: G$ t9 _        //#pragma omp parallel for' A! z& z2 N( _( ]+ e
        for (i = reali; i < nconv; i++)1 q1 T, ]- l) B$ D2 W% a! Y
        {! K5 B* v5 Z5 V9 G9 u5 C$ }
                temp.re = 0;2 v& W. ^3 o+ q+ m
                temp.im = 0;
" M& P% L: a; Y                i1 = i;+ t/ R9 T0 r: b* j* Z- c' Q
                for (j = j0; j >= 0; j--)2 y# l# D7 k: `9 a7 b
                {
' J- l7 h- ~  M9 W                        /* floating date operation */5 Q$ Q" e; ~( J8 \6 i  D  w
                }
+ i( `- h' e$ J9 V( S6 h7 E
        }
) c* @& a6 Q$ d9 c' h% |6 I}1 @6 F& s" H/ s' m  [
9 }' ]. i6 P$ B3 o
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样/ V! P0 X+ [" y5 {2 o% n# [  W

5 o( c# V1 z- f/ e红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
; |! |- Y! Y# G) }现在call xcorr 100次,耗时78s.8 u6 _/ T6 ~# {. M( U3 t7 u# Q

+ h8 m5 z& X( X# J1 e如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
. \. ]$ x, c/ V9 p4 x) [  h
" ^- w" X  Q  L9 i( \5 ]
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
, p9 Q1 D" l; X( a9 yMaybe Debug mode?

8 S6 f4 X7 `% `: w2 ~& i7 ^
8 o$ m; W& ~" T. ~) L" d不应该,看我上面的回复。
7 p* F. J. P( n( k/ ~( z" Q. r6 d+ @8 q* o- @
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 9 a* `6 L; m4 M! h/ y6 D
雷达 发表于 2022-9-24 23:54. B. E! m& V' E8 T5 R
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
% ~8 m# L9 ]! @: z% @{
# N+ k/ K2 H- {7 j* C# z1 {7 t; E        comp temp, xtimesy;

; U- D' U8 u4 O0 `" i& i6 b( h2 @5 I3 b* o. i2 a# w3 X; O
这个不是这么比的吧。。。
' z- Y4 k$ Y2 C" f; A5 D2 \2 p1 e
7 f; q4 P# Y7 Q" K( [; m您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 \6 K5 y- F& p& D) V) T
. s3 h+ Y1 t6 D  f# `而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 9 {* d" d: C0 f% `, ~/ J* U3 Z
数值分析 发表于 2022-9-25 00:20
# a: v% O- i, L. ^# S5 _% n这个不是这么比的吧。。。& q5 D# Q0 |% \% g6 f) T4 ]1 I

) f; H5 f) R) k) y9 o: d$ w您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
. \/ b) ?& T- [' A( E! t' U& S
: d7 l4 b4 j" D/ I, ?
有道理。
& e. z* G) k" U4 j7 O0 u& ~所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。6 l) c% Q4 ?& Z- i( ^
  N. q- w. y4 {! ]; ?: P1 T% q: o# v
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:465 h; k' {" ^% k8 A+ i' C5 |
有道理。/ g& {0 r0 `+ U( W- s# Z
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

' M# d+ [2 e& X8 B8 U你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
# }7 u6 N/ {% C/ x; nWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
8 A+ ?' v$ n$ t7 b$ f这个不是这么比的吧。。。% C1 u  Q# e' S1 l# i$ n

7 \0 h. C6 @* P1 D+ S+ @0 m您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

' p7 s0 e9 p8 k1 S9 `9 }& I0 l, Y0 w9 C
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 5 a+ q- ^% ]" ?; k7 Z
沉宝 发表于 2022-9-25 01:48* F. v4 _0 |/ [9 D1 L  y, u) x
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

9 q9 x! ~6 T  C# F; @1 e& B; `' |7 k
是的,兄台说的对。
4 l# a5 Y* W. {' Z! |4 _, v
- n7 O4 T+ Y8 \4 G7 t# P其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
2 K1 o8 }! j5 B+ h$ p3 S$ P9 j, [/ t
) k0 t: h. t9 f% |/ _3 S9 a雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
, a6 g% e! [% @, g* S( i" w% ~( v( L! E/ I& `# G3 g
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
* {7 k) Q# l+ ], x! @, C! a) r: k* p9 w5 x; N2 V4 X
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 # |! S* I. H1 m% J6 |8 p! j  p
沉宝 发表于 2022-9-25 01:27
2 r5 E) f1 v5 c- q: E: \你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

# O# w9 D7 d3 F) ^4 N2 M9 L9 W! P6 ?( R+ J9 ~7 R
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。; q# z' A, @' S# C* V3 p1 b
# E" r7 i/ Y  ?& d4 X
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:474 k: r6 S. l5 N4 w1 |- S6 L8 F# G2 J
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
  o/ L2 e( v. D$ k3 r& B7 s# p4 Z& D
时间差一倍的结果可以接受。  D# `8 n% }4 }

( t& T2 v2 J# Y8 T你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
% T) H+ s( p& u
雷达 发表于 2022-9-25 04:47
1 J  x) O" K+ ]8 I3 A又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
  P4 ?! H4 m+ S" [

2 S# |  @- X; ?  P" [5 q
2 A( |1 w4 V. {) C
$ R5 H2 P7 i+ F% ]: ?4 J能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
* Y+ G4 [2 O: H3 R( {" D( h
数值分析 发表于 2022-9-25 14:585 W6 O$ f5 y0 m9 l6 {
能不能把这个也贴上来,看看和上一个有什么不同?

" `( K; Z9 Y8 `- x, F理了理思路,重新做了一个测试。. k/ Q0 o' H  G& l$ t
做了两个 vector 和 两个 float *, 都长 100000
& u- c5 y% n8 W/ h# y& A$ H外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
4 C, z* C4 T3 G$ Z& D: {
3 K: L; }) V6 g内循环试了4种方法,- U0 [' y4 g6 U, D9 G9 {, O0 ~
1. 直接调用 vector inner_product 247s
$ @4 T2 y3 D/ i4 c% S5 j* O, P, Y2. vector 循环点乘累加 237s3 F- S1 A+ z# ]
3. float * 循环点乘累加 204s. G/ B8 Z0 O& z7 p, {  Q
4. 空循环 100000 次 202s; e5 @; Q; f. l2 _. U

% v, {% t6 x0 A9 {" [不做内循环 200s% l( u7 M" h" C. q. H" ~

$ }! p2 _8 x- r1 x* q: o你昨天说的对,内循环本身占比是很小的,大头在其他处理。
- D* \& w) a; H5 R% W8 s另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。9 g4 C% V, c1 d2 {
* T) v- e8 V' B, E
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)  ?% T; j  ^' I1 [# f! R; R, j
6 Q4 O" W% f/ S, e9 c: j: I2 |# M
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)* [2 P3 r& ~1 P1 T

% O6 J' J6 `6 y* O# Y
        std::vector < float > vec1(N);5 s4 m) Q9 z& q& W- a+ d: j
        std::vector < float > vec2(N);
0 b+ b. y5 Z/ o/ Z& {8 E' G6 R        float* b1 = new float[N];
9 o7 d% b3 c' j$ F4 q; k. ~        float* b2 = new float[N];
" f* O* f3 @' ~6 l; R; u0 H' |
        for (int j = 0; j < 6000; j++)
4 G# @. `( y! G" W; F- v        {" L/ W' j+ x7 n# u+ s" p/ I: g# N7 X
                std::generate(vec1.begin(), vec1.end(), []() {2 h- E5 I, b$ |0 d8 h$ h; J  d* q
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;' L$ g& C) x* d+ W
                        });! b% o4 i; C8 E1 Z

2 B( F4 w4 a7 I6 g                std::generate(vec2.begin(), vec2.end(), []() {  S2 r8 {& c6 y
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
/ f0 w* [8 F( \                        });* V: a, o  n; ]- _, a

6 O  j2 h7 G% A) ~% \                for (size_t jj = 0; jj < vec1.size(); jj++)7 g; k0 f3 s& T! k/ G
                {$ X( `6 z5 V/ [' A* v7 S
                        b1[jj] = vec1[jj];
) U7 ^' V" i# w& [& h                }
8 k5 M5 _. e: X. O0 R) [
! \) z  j. p# m$ ~) _7 l3 `  ]' B5 v                for (size_t jj = 0; jj < vec2.size(); jj++)9 N4 |+ x+ `' L
                {
6 Q  F2 U5 |% I9 G# Q% G. D                        b2[jj] = vec2[jj];; |) n& J: h/ K& ]6 C
                }7 Q( u+ g7 k+ \5 H* [/ n
: r6 _* L" t4 u' p9 @
                //Method - 1  N=100000 247s  
+ a4 K& t. F) A1 `                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);( Y% w. A4 K4 v' `8 |; k) K6 R
                                * a; p  U; C' U! t7 \" [
                //Method - 2  N=100000  237s
" k* P9 A) }- i* l* b5 g                /*& V3 ^8 b) i8 @; }/ [: ]* N
                for (int jj = 0; jj < N ; jj++)
- q. _' ]) i8 D! r                {
/ P# b! h+ v; G1 V, D7 N                        fresult += vec1[jj] * vec2[jj];. I% |! y3 r: {2 r2 |  P3 q
                }2 d8 p$ F# E/ a% x1 c
                */
" B! C& F5 D9 Y  T* v" \& _& I                                : `6 u( ~3 J: Z. r9 G" W
                //Method - 3  N=100000 204s
- P; W& n! M! A' e0 ?                /*. l0 ^, r7 p' Y0 q; w. g! I
                for (int jj = 0; jj < N; jj++)- N! w5 w/ ?$ L, }: B
                {0 K7 \; j  ~' L3 [  ?5 S
                        fresult += b1[jj] * b2[jj];; x2 b, M1 z; m' p# J6 s2 j
                }
  s5 Y1 k' _# f* ~8 M0 ?; N                */' f, ?" G7 g# m# Z0 g0 {

7 S: _, b7 K) ^$ i+ Q5 I                //Method - 4   202s. ~! V4 E( b. k* d
                /*+ M/ t( E" b( V* h8 Q8 l
                for (int jj = 0; jj < N; jj++)1 _) p! S) C' I8 a/ |3 J
                {
, d, W  q. v9 r# l# j                        ; ?' O7 g' |) Z$ d" O1 u( Q: M* Q
                }
/ R: i# u2 M  a# A! s0 E                */) }, ?+ j' P) d$ ~" [
                //comment out all methods, N=100000  202s                % l. r' ]  X6 @! ?3 U5 j
        }
! L, W( z* U& U: p  p, W4 m; h
( b0 s  b" C- ?7 O; @' a1 t        delete []b1;
( f2 Y' \3 C2 S; |  f% `        delete []b2;
; y9 w# }* S4 x" f% F  L

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?5 ~# h0 z- n* y2 W2 O' T0 J" `
  E# w* E. Z4 [: Q& \( p
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
% H. w' ^' W6 O+ b* p
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
5 H) @# z& I9 z3 N5 N瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?5 O8 ?2 q: V1 R

. r) M4 Q9 p% r& O$ q你第二个试验里面的j在循环里面又重新定义 ...

/ T" Q) e( Q/ l; u$ A* b% {& O: M" ^内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
' X( |$ o0 d! k% M4 M
; c# W( L3 e8 k- j0 u0 m不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
# }& u: i& P* c内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL8 Z" @% z1 i! }$ U! i. L/ \
6 y. K; ^0 w0 _/ L0 U. i
不和它 ...

* \) I* W  o( O+ O5 g% @) ?4 f  @- }' S2 T8 l$ E0 i+ l. a
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
4 h3 J0 u( h1 u( J; u- g后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54% w& ]) Y, U* W9 i: m3 w
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
8 z4 Z- }9 G/ G& s: m; i) A/ M{
; P5 U, P8 \- A$ F2 R0 X7 l        comp temp, xtimesy;
; ^; V& `7 v4 n6 M! \/ q2 ]
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
2 y# n- G9 C# F6 k9 \# q7 c+ g/ ?内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
3 e+ a+ P5 c- A) I, |, v9 jVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
+ ^. Q! d# Q8 ^! o- p3 u3 d理了理思路,重新做了一个测试。
! R# c, H' u- f1 v9 ?做了两个 vector 和 两个 float *, 都长 100000% E2 A3 @7 `4 v; w& I
外循环 6000,里面先做随 ...
9 \1 D' F9 d4 }+ G. k4 b
这个时间是从哪里开始算的?- ?: }0 \4 w' a  n
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。3 O1 ?9 T* r( K2 k7 X
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
4 s- m+ N/ I) h  V/ a$ s这个时间是从哪里开始算的?
. D# ~. m3 i/ u  z( L2 |' w我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

% ?9 u7 i4 r3 B7 n" X: X( i' p我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。, f1 j, J( D, s+ Z$ A. r
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。+ }7 a% S* v' _& I- k' N. p5 {
与此对应用数组(指针)花了2S
0 ^0 u6 Q) a4 y' V  X* u) _你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54& H/ M4 f. d" A4 c: x( @+ _
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)1 v) \6 a' Q( l$ Z2 ?5 N7 h
{
7 _+ O2 U. z4 K; P/ e" x        comp temp, xtimesy;

: `$ b( Z. |* w1 p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% \7 M* i1 j+ [' u& V+ }( q) c' Q- u1 E1 r

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29' f9 m6 u$ o$ J
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗! {, v  I$ u' H! h" {3 S8 t
+ W( P+ ~1 q! ~* l$ U
...

$ L4 D& |% \8 c你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
1 |. e( f. f8 ?5 x# u% Z* _" Y. p( F7 l) n0 K
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
  W" R* |: i! e7 W. x& u) o8 O1 @# k5 I; D3 r5 M. k8 O
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
0 c) T8 ~  ?. @3 ~& v有空时我会试试 SIMD和并行,看看能提高多少。
4 y, P- x8 A& q: e1 v过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。6 V8 Y5 d8 {5 b
谢谢大家的讨论,I learded a lot.  红包已发  + L  [" \. ~( k; Z
+ x* s0 W& L+ ~
, H0 |$ X# w' b$ g
. c; [8 x* l3 h/ j$ t6 l$ ?! X. k" |  Z
) ?5 j1 s# Q! R7 ~





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