爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?% s; j* _+ d# C- X/ W6 y4 Z5 ~+ K  p
7 N+ s3 y( b2 a' @2 z' C  }4 z
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。0 H7 v9 L3 e5 Q3 [0 X0 g& {2 z

* l5 Q+ p( T9 q' M: W) w: @速度优化问题真的很有意思啊。) ?& q5 q. M  g0 z& \# B6 A
5 x! J+ t" |0 ~) k/ n7 K6 b
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?, o1 a  @4 c  k, P
把代码贴上来看看?
: P1 A+ u, D& ~* s; S" l2 M+ M
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 0 @2 z; F0 d6 g# `3 c* ?! H+ w4 C
数值分析 发表于 2022-9-24 23:04
6 P* B# k' F5 i. B2 R* F拉下来?拉多少?
8 d# z9 @$ l* x把代码贴上来看看?
7 ^7 L" K, F2 z7 X/ d
9 K6 L" l# f/ b* Q) Y7 l: L) z6 _
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) ~, F8 Q; Q6 A1 K2 I
{) ?+ H2 ~2 a: ?  W
        comp temp, xtimesy;
. U8 E3 O& y1 Q3 b8 v        xtimesy.re = 0;
; {; c+ F: g6 R2 Q) x7 w, l7 T        xtimesy.im = 0;
- o6 |2 y5 v5 l* l% M        int j0 = lenB - 1;
! m2 ?8 `* p# k        int    i, j, i1, reali;
3 B( L+ N3 m) E0 B        if (lenA % 2 == 1)8 I( q; Z8 \/ Q
                reali = lenA + 1;
: n. k/ V1 V" ~- b        else- Q% B5 |( u/ L3 K# x8 K
                reali = lenA;
. i5 ^4 h! l6 {        reali /= 2;2 W# j3 ~- s8 G3 f6 Q

: T. Z  r# M+ X0 y; u        int nconv = reali + lenB;! v1 h9 W7 ]' @; \2 l
        //#pragma omp parallel for& B  h; A6 c! h  r( E
        for (i = reali; i < nconv; i++)
2 T1 E6 d' J3 D& B        {
0 k1 o/ k/ V3 Y" h                temp.re = 0;
6 s- e5 n7 M; k& k/ n                temp.im = 0;9 ?" L. ]1 k7 d
                i1 = i;* ?, |' Z9 _& h( _6 ^: x
                for (j = j0; j >= 0; j--)
; I% ~- e4 p" ^: `                {8 W0 [0 Q& q  }2 L
                        /* floating date operation */- J. z7 O' ~- D7 Q$ ]. D
                }
0 S& k) y6 d8 t8 _  Y; z
        }& t$ N  U9 g# c. `4 `4 |  E: D* c
}4 M0 X; ?* p4 ^- j* l

2 @! r1 p4 [7 D& z, o& q* }xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
0 A5 l$ v4 u9 p7 S
, v/ n2 D2 q9 ~' `+ i* b2 ]9 h红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。3 ~; ?7 B) t" D
现在call xcorr 100次,耗时78s.- }7 Y: F0 J5 _; O7 x6 g
; Q* Y) @; y2 Q! F
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ' p3 v9 B  |1 y! ]5 ^+ s: B8 @

% n5 b; l$ y  o, w: ^
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33) _- J6 l$ e% V( q
Maybe Debug mode?
1 s' K2 M; v3 U

5 n- z4 J! ]) P1 Q1 q4 v% [不应该,看我上面的回复。, y6 T: N+ d; ]; E& h, ~

" x5 ~; I# i3 R* ]! z我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 0 R2 @1 f1 z: Z0 z* k2 M7 Z2 d6 E
雷达 发表于 2022-9-24 23:54
' i% S& ^6 X$ S8 ?" s/ `( x$ Wvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 H; j: ?" P  g% _{$ \3 C) L$ m7 s2 G$ T: G0 d. g
        comp temp, xtimesy;

  k! i6 c9 n8 O  b7 N; P$ \! o* j6 n* ~& G* ^" W5 |8 k. P8 u
这个不是这么比的吧。。。2 T+ q& \  g1 z3 _
9 z. @8 J6 P4 _: ~; a; B
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。; q! j  C0 |8 @$ t+ H

: k. h1 N6 ]' [- U1 {而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 ; c! O& L3 R% {8 r
数值分析 发表于 2022-9-25 00:20/ p" b' N! z; H0 P: s
这个不是这么比的吧。。。
! }6 ~. x! n/ g( h" g/ a/ J% x3 r  \( }. C+ ^- G5 M9 x& f' `% N$ N
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

( z* J/ R* }4 b3 ^9 q
/ u' R( `, H5 j# ?5 X1 [' ^& a, c, I有道理。$ A0 r) H. t9 I3 D" d1 a9 v' j; X4 v5 w
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
  ~& _8 t$ A, e6 X' |+ q% J& W. \* T; k: W7 h  a
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46# T$ i$ O- V9 H3 b. q) A) g
有道理。
9 l4 [* x. g) s$ ~- g. X所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
) s0 o3 @- C# H& o6 z' I- \+ M
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多6 c6 N+ f" a7 ~
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20, d7 a% @0 c0 T6 o5 |
这个不是这么比的吧。。。, n$ d8 O0 |$ _0 y9 N

! v, _) y+ d7 b. B您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

' W# s5 P8 v- b+ c
9 a! H# s3 n- x' Y8 U2 b; p3 p# ~现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
& N8 x( k; `1 N6 h
沉宝 发表于 2022-9-25 01:48
9 U! `3 t" R* I/ z* l现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
" I1 Q. s3 ]4 m3 {( Q5 P
( `5 G7 [" E6 k* h
是的,兄台说的对。
6 C- F1 Q5 x" Y- F7 J! ]. F) i' T4 m: b% h" C8 y, J
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
. [, r  y' Y: G+ z1 g; `* x6 Y7 D+ w! F" X9 D/ r4 }, k
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。0 J( x% L" C9 P. Z& @* J
7 E2 Q. O' m2 p  g, f8 N6 G. |" s
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
; }$ |  f  `8 v" i& S$ q  X# X5 J9 I4 j4 h- s" |, c/ e
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
# k9 a! D+ {. I! t2 M
沉宝 发表于 2022-9-25 01:27
0 \2 }: y, _9 k! ]" y7 [0 R' ?' R你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
5 u9 O8 N6 [. U/ [, t! A

6 Z1 l- U/ S* u4 a+ }又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
6 G2 X9 r0 x- h& P- J& ^% c, M! \" a4 Y1 `5 K$ v
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
1 V5 a. c* `, }3 B, l又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
+ c) F: `) e, p+ o" y2 N: m1 I
时间差一倍的结果可以接受。; k+ O  a3 Q8 r% \! @

8 ?7 H* V) f/ _6 d4 ^& b$ `你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 # B8 o0 ?6 `/ a9 H# _
雷达 发表于 2022-9-25 04:471 `  E8 P# |+ a! e% y0 s
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

9 V4 X  d/ n! P1 b5 o
3 u# \( F# W  K8 M4 h0 K8 @& o& b  ?" @# b
! b. `/ x* l1 C; D, V1 Q
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 $ u" M6 W, c8 u3 [! L) B) i2 p' L
数值分析 发表于 2022-9-25 14:58# ~5 U  x3 ]" D# \
能不能把这个也贴上来,看看和上一个有什么不同?

3 [1 ?2 j; M3 `2 t  B( V2 x1 V理了理思路,重新做了一个测试。( f$ V0 j; @/ K3 G( Y
做了两个 vector 和 两个 float *, 都长 100000
, n) p+ _: [, Z: G- G0 |) o, o外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.7 I& r$ u  \, E  J/ J

1 a) M5 ?, h7 g3 w' j0 X内循环试了4种方法,
2 K- L) D8 @- i0 ^! F1. 直接调用 vector inner_product 247s
' a: x  E" q4 s0 ]5 |5 y2. vector 循环点乘累加 237s
8 q7 ?( d# l  y' C( U2 N3. float * 循环点乘累加 204s- q; w2 J6 u# X" z7 W. y% g/ e
4. 空循环 100000 次 202s
+ y% A  A& z7 Q, Q! b* D
' ]( N5 U/ r) @" R& q" O不做内循环 200s
- u1 K3 Z8 p" T8 F- O( t- a, E. n3 _# X0 [; y0 b
你昨天说的对,内循环本身占比是很小的,大头在其他处理。2 B: h  R' a2 v6 J* ~
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
6 i5 G; z3 q! j+ L5 x' q- r* P& H1 e# h# X& {, C
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
: }3 A/ G! u4 C) }: T2 f0 y$ Q( i+ x7 I& `# H
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
% K. W! g1 T8 G0 \# @7 }" O: E8 M6 j; E# _
        std::vector < float > vec1(N);
' c. L& `9 C$ F% d9 l+ ^0 f        std::vector < float > vec2(N);
3 i( O; O! d+ V9 }        float* b1 = new float[N];
8 R3 B8 x  E5 M; I! b9 [: v) ?6 d        float* b2 = new float[N];
3 G; b4 Y  n  k+ i5 B& E" n5 w4 ~0 P+ R
        for (int j = 0; j < 6000; j++)2 k. A5 P' \- X
        {. f5 r  C  [' `  i1 ]+ x( m. v
                std::generate(vec1.begin(), vec1.end(), []() {" \0 p9 m4 U! u+ T
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;0 F) Y2 p: D8 V3 p9 I. L/ D
                        });4 L4 H3 R. G8 N, V
0 W$ A6 X9 ^* D
                std::generate(vec2.begin(), vec2.end(), []() {
" R: i0 t9 p9 I$ L! W5 N! r                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
- @% J; h% R4 V; m, |/ v" ^                        });
1 f4 r8 z/ r* f$ Q- r1 f( _
+ A, C0 k" b+ ^: _4 f5 [                for (size_t jj = 0; jj < vec1.size(); jj++)* A7 D+ R4 _' o2 Y0 X# b
                {! S/ i6 r9 m& @$ E7 T
                        b1[jj] = vec1[jj];
5 [8 v# {& q2 H                }
9 b# l% A# v# k. N- `
" u$ P$ E( V6 @7 [5 q/ x                for (size_t jj = 0; jj < vec2.size(); jj++). V; i7 X  ]% z1 V
                {
* a% g! h+ X! l/ L7 k7 u$ A6 S+ c% c  s                        b2[jj] = vec2[jj];4 T! t7 ]5 u/ i3 E2 n6 E; J
                }
& M2 L/ V* L7 U8 f/ L
( Z- r' o  Z# [7 u* c                //Method - 1  N=100000 247s  
% r) u* }3 r/ y                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);" u5 e+ E  e2 T' g+ r  L& G2 _
                                1 h- _7 b4 i1 w  y$ f
                //Method - 2  N=100000  237s
) d0 @. k1 d4 x8 `* P8 `                /*1 D$ B2 i5 `( }1 }5 c
                for (int jj = 0; jj < N ; jj++)
8 U& @$ F5 @9 T% E) @; S1 e+ P! ~& i                {
( ^0 R7 O$ ^7 V& `& r' ?5 ^                        fresult += vec1[jj] * vec2[jj];
2 L3 H" ~3 c3 y9 L# {; v                }4 w* ^. M. j6 V
                */' S% d; Y* G' f: d
                                
+ @, ]) }! R5 z# L                //Method - 3  N=100000 204s4 M2 H$ U) w- N% G$ R
                /*
9 v, c2 k+ k: E" @; b" `4 J0 R) N                for (int jj = 0; jj < N; jj++). S  h5 b% P  H- O9 @: L
                {; u& J6 k0 I6 q8 y: O2 C" K
                        fresult += b1[jj] * b2[jj];% G3 t, J1 c9 \2 b8 l. E9 C$ E
                }! w' [( Z' Y0 g2 r! d
                */+ x( u0 u0 V7 o) u( w

9 t6 {" y2 ~% N/ T' [, t! }- R. E                //Method - 4   202s7 A8 [$ ?6 S  j, [. p$ u$ y
                /*8 G& r0 o, o1 y, S, D9 k; k2 U
                for (int jj = 0; jj < N; jj++)
, I/ Q, O, f, D                {& n4 b, `$ `' X0 q9 }
                        
) `3 J2 z( X! y" h' i, @                }
% y7 S% N0 G' M$ D/ y+ o" ~                */. j' O7 y" T' [/ [' V8 B) \# U  z
                //comment out all methods, N=100000  202s                ( P1 H* Q% Y( m) \( `
        }; ~+ e0 {! ^' d

# t. f3 K$ g: k3 F9 n        delete []b1;
( n+ o2 @2 g% {/ I5 j: @        delete []b2;

! z  z. r& Z4 Y: I
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
, [0 d! o( x0 b2 r1 Y- x2 d- Q( w3 C9 z, h3 Z1 P: [/ C: ^9 |' @
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?. r" t+ e7 w, K! X

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15# o2 x1 R$ O2 W
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?1 O: ^" [" P- C5 \8 V) a. S

: G3 Q* _' i1 R' s9 I你第二个试验里面的j在循环里面又重新定义 ...

$ @( y! R" B2 p内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
/ J5 ?5 x% f  ~& {5 ], o3 p% K, Y, C
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
1 B/ p( F5 K9 Z2 T; E$ J/ A) G内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL0 `" K* v0 Y/ A' z
2 e# H. w: V: I' K4 t6 e
不和它 ...

- V* \0 e: c" E& @" S* v9 p# P- a, g8 M: G8 \( T0 g% C
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
/ R4 K# Y, t) n+ s- G3 c后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
/ ^6 j# X4 y+ ?9 U% t9 Q) [: evoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)6 M, G) y  \! L8 I# X9 s
{* _4 _7 Z, Y) w) M7 q/ a$ }
        comp temp, xtimesy;

$ o' R5 w% s: j5 b这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。7 p4 C, g. v) z, c/ f) M2 g6 @5 r
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
" U  k! M/ D! H( a* ^VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30/ w! {1 j& e0 }& N
理了理思路,重新做了一个测试。
  V/ U( m9 t- _7 L, W6 c/ B' k$ i' P做了两个 vector 和 两个 float *, 都长 100000
) P% m$ Y5 S/ B! K5 ~7 ~外循环 6000,里面先做随 ...

1 V: {- O9 A' ]0 s这个时间是从哪里开始算的?' Z6 |$ G2 j% ^& I
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。2 g0 a1 M) Z& |/ u8 B9 o3 S
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
# _7 |0 P4 o7 n# }* W1 \7 u1 y这个时间是从哪里开始算的?  Z- C) e5 {7 h* X& o/ S  b
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
3 _" w- P' u& y- \1 m0 a- M6 @
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
8 y: ]8 O7 x5 N2 A3 |你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。7 o( S, m: N' c7 j& [. B
与此对应用数组(指针)花了2S7 c) K, ~# g7 P; Q' A$ _  O
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54) e" e* Q+ I' ?2 R  A% f
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
& f5 ^% v' Q9 t/ T* Y0 n{
9 a' K0 ~, E. Y8 Y        comp temp, xtimesy;

- a1 l1 _! N+ p! t4 Z  p我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
+ R) {. j- T; r( a
* q! i0 e- T: _
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29/ H* w5 ]9 W! q8 M$ w
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
, }- W6 R) j2 i! a1 a
) M4 k+ C4 \3 V  y4 z, A  \# G ...

+ u# c) ~- C7 K% K你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。# N8 s4 s) s( [3 H) H( D6 v
) y; h! b& v# [- I$ A) C* U
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 # q: u" _& M: M: m$ ]

" f3 E: ^' J$ R4 }是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。+ |1 X  d( g$ u, r4 I3 M+ U
有空时我会试试 SIMD和并行,看看能提高多少。
' R+ ]5 i! E$ ^  @过去7、8 年没有正经用C++ 写过东西,没有 sense 了 3 T0 m) O, }- u! m6 ?! r
谢谢大家的讨论,I learded a lot.  红包已发  % l* P* U$ t( f, H6 |" l" H' ^
9 A. ]) I- |9 M9 `. Q8 t

( |7 P; S/ W6 g! W- E& I: D& A- R8 Y: e( J

$ P7 i; v; I" W0 ?1 z: K5 _+ F




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