爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?" D& h) ^6 c) @% r. p  v( o

4 e; G/ i5 K7 X- B  i/ V. _! X自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。$ Y* H3 [8 ^$ a( D# F

: C/ H  P1 _0 J8 \! o速度优化问题真的很有意思啊。, W# T6 K9 `0 e: N; e7 _) F1 u
* z3 z/ Y9 l  n& V% B
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?% g3 g- d+ g& Q) K: v/ q1 b7 W& m: K- W
把代码贴上来看看?7 i7 W" c( S/ `. O; J7 |

+ K& `$ j8 W% R2 m$ x7 r难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑   d3 c; A5 W/ D" x# a2 [
数值分析 发表于 2022-9-24 23:049 K7 t+ n9 ~2 ]# ]
拉下来?拉多少?  v& a6 z, h% ~- z
把代码贴上来看看?
% B0 L/ I* H6 Q( h& C* }4 C1 P, Y
' d7 s# q, Y0 ^$ _: P
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ x2 {1 s8 @5 u3 q# n3 \{
! }; i( D& u; O& o$ M9 P        comp temp, xtimesy;
; `& F% _+ R$ S; w        xtimesy.re = 0;
3 l# [+ \) c5 C+ F        xtimesy.im = 0;1 R) F2 i% w) a4 V" @6 q% {) o7 }  B% y
        int j0 = lenB - 1;* v. t# D1 ~/ H  C8 P4 Y% ?
        int    i, j, i1, reali;; h7 \; R; @- V! f
        if (lenA % 2 == 1)! T1 h/ E. l# w3 z: @3 _
                reali = lenA + 1;! N' X: ]' R* H& g
        else. X) j) \; g7 o
                reali = lenA;- V1 Q0 E) u+ Y/ \- j$ A/ F+ _7 u
        reali /= 2;
8 P) s) Q6 Y8 D& d
( @5 h5 c; F) m! F3 D" w9 U        int nconv = reali + lenB;
* U/ g$ h" i/ F* I, ^8 n        //#pragma omp parallel for+ E" o5 _$ `' `& C/ ]
        for (i = reali; i < nconv; i++)
  T, i0 n6 ?. F6 C7 D        {
" O& L* S8 r+ a& y                temp.re = 0;
% k$ j4 b+ E; V+ p, @                temp.im = 0;; u9 w2 k! N& O. B6 |+ R7 j" ^
                i1 = i;  d; }, U4 m0 T4 I* D" }4 u
                for (j = j0; j >= 0; j--)/ n: d% C9 ?% V' K% D
                {* \) c1 e& O* i2 z& M2 m
                        /* floating date operation */# v) \. A& m" o6 s
                }
) E/ C7 L1 K) U" C8 J
        }7 n+ Q3 z: i  {. m' N
}3 n7 i+ R+ j/ H# e# {) S2 M. G1 X8 I
: }# z: e7 \6 _8 w
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样7 I' k( M4 k9 s( M$ C/ _8 q

; W: P2 o# H1 J红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。! {, W( F4 R" O  h
现在call xcorr 100次,耗时78s./ X  ]( w3 E$ P1 v9 l

* ]' O+ Z1 E1 e7 _# N! I如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
+ g8 ?, f. j# W- I" g( W0 b
+ S" o" i4 t7 H
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
  `: N& e' _# V5 j0 }) |* `2 f8 XMaybe Debug mode?
4 ]$ R; d" n& ^- ]# F' c' Z
9 D. U* m8 {5 p# J4 q: n# m
不应该,看我上面的回复。6 F9 \2 W6 s/ x# _

+ c3 {  B5 o% S' I3 s6 I; I( _5 g我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ! [" g! Q  I( g: e" A. A
雷达 发表于 2022-9-24 23:54; ~4 C9 a* j1 C  Z  y, X
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)4 q. i$ T2 L6 n- X' o
{) r! r" h; `5 }: D8 a
        comp temp, xtimesy;
. {6 i; m0 A2 u% m" i9 ?
! i5 q, ]) a& f" d; J, T
这个不是这么比的吧。。。* e, D2 u: `5 Y0 B/ }

4 Z) j2 w- j' Z% W$ j# w您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。5 Y- [7 T" l5 }0 A. d
% u' `3 F6 u7 Z+ Q
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 6 P- Y  d* c5 d
数值分析 发表于 2022-9-25 00:20
& o+ `3 j, O) u+ M' _9 X% J/ \这个不是这么比的吧。。。
) U4 h# W( h4 o) O% q' B) x$ }  d( `/ r6 V/ W
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

# n% o: e  H# d& v, E
* V% ?7 _: b/ Y& e2 ~有道理。
; g6 P+ n2 A" {% N& l) m所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。+ [7 Z  c' |( K0 P" r

! f9 K+ j% r6 w4 R0 @0 w我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
0 J$ G1 w0 I0 ?1 i! P8 l有道理。& E. T) ?4 a' @* K6 T" q# g
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

8 ~# ~! N) j1 g' s" d你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多. ~$ U- m4 p; H" L; U" l/ d
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20' g* P: ^# a# V4 ]  @9 [
这个不是这么比的吧。。。$ p1 o  u6 p2 D$ c) E
* ]: r3 e8 r6 t# \* h2 {
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

6 I1 u7 W8 m4 P3 c0 I
8 J3 i9 j4 n( y1 e. |9 f现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 . F- V. {7 [5 b' @
沉宝 发表于 2022-9-25 01:48: ~, m% ~+ d" `  A- h# }( a9 W
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

4 U3 ]. N) `. ]& o( i4 c
. ~+ O4 R+ ]/ f6 W2 }3 q+ d8 G是的,兄台说的对。
5 T; H: G' x9 s6 a
  `! V$ Q0 t: V其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。( I. j% S; C4 C1 f. K
9 d- X) A; a7 r  j% `
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
! C. E# n6 v5 x3 t  Z
% K& o- [, X: t2 r% ?: a/ K, X比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。/ C& ~6 w8 r. w. H% N% w' X$ Z: f
& e- n0 @+ K, z  i
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 3 v/ O: F; o5 s: ~6 J
沉宝 发表于 2022-9-25 01:272 B7 m  R2 j# R8 l  V+ T" _# l" S- p
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

, I( l/ q1 s. v$ Z" r$ P; `0 D' @. }" _5 G8 J) u! a/ o/ k- K
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
# w+ r2 y/ d3 J1 G2 g
0 U3 r8 U% ?5 B& e5 O. F我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
0 i% f) J' m* o2 L$ d3 _7 h又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
$ x* C: f, J  ]0 U& w
时间差一倍的结果可以接受。) i; g/ g. M' Z
$ c; v: h$ A& t, T8 ?1 b
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 * }9 j9 E( b/ n, D8 k3 t
雷达 发表于 2022-9-25 04:47
: L3 y4 C3 s1 _5 @7 `& @又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
1 x/ z8 D1 ^0 o+ c- }% ^

% }5 I( u) v* t! U) Z+ @2 y1 e5 N
. z0 r8 q6 {# X% d& p
6 W8 B4 W& K4 v" K' e8 N# b  q7 f& R' s能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 : o( h/ q& W% p4 l' p8 Z% }6 T8 G
数值分析 发表于 2022-9-25 14:58, L9 `1 V! g1 d% o( L8 e6 Y
能不能把这个也贴上来,看看和上一个有什么不同?
% j2 N: s- u6 ?$ H6 p
理了理思路,重新做了一个测试。3 V9 G& ~+ m. `; a
做了两个 vector 和 两个 float *, 都长 1000002 p' z5 m, Z4 P9 I7 h0 V7 k
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
) `) Y: I( e- s7 Y7 L5 {: d+ c. _; d0 i
内循环试了4种方法,
2 ~) q* H- h' H. b, F1. 直接调用 vector inner_product 247s ; h4 S3 P& J; k
2. vector 循环点乘累加 237s9 {- X1 c7 T# p- T3 Q9 e
3. float * 循环点乘累加 204s# w+ O4 b6 E5 v/ k. k
4. 空循环 100000 次 202s
: |- K) w( j. s0 J! |6 `% O. d* U0 n: O- U  D
不做内循环 200s$ k) M% z/ M7 |# ]0 A

: g# ^8 {: X) R3 i, _( _, I5 j你昨天说的对,内循环本身占比是很小的,大头在其他处理。; r0 w- f9 x/ s- \
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
0 m6 g+ \( B& I8 K3 u0 ]8 i0 f1 M5 H# ~0 B$ L, {
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)& t! T/ k( F  |

' L3 a5 ]0 W* s7 E& O. H; t  v(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)+ E  I% w+ [- G6 s! a

0 j5 x! {, x, I3 i) ~2 u$ D
        std::vector < float > vec1(N);  {* G& \. Q/ N) N! V) h
        std::vector < float > vec2(N);
* r5 ]% X5 a9 N        float* b1 = new float[N];& V- |& S- S) C* }/ @3 z
        float* b2 = new float[N];
! U% J8 h! K. S. W9 M9 }6 C7 X$ K1 c9 C6 X* ^2 D5 u; |
        for (int j = 0; j < 6000; j++)
5 f: L+ P( o7 w/ b        {
  l, W% {3 D- k0 v; G                std::generate(vec1.begin(), vec1.end(), []() {; a9 Z8 ^+ R. g; R  X# e. [" ]8 o
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;: b1 a4 {# d4 h8 V- D# K  K0 X3 k
                        });
- z% y4 L# ]+ J6 m: L1 M7 o. Y: ]$ t. l( C& F" t8 c& V: V) @! E
                std::generate(vec2.begin(), vec2.end(), []() {; R; X9 w- O4 }3 ~: a
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;2 \2 X8 u7 u  I. x: `
                        });
' @* r0 z. ~" O' ^! d* f# `4 T% u6 b- L6 j
                for (size_t jj = 0; jj < vec1.size(); jj++)
/ r" k  g7 f. Z$ s/ [                {: l  t6 ^+ O5 m0 H6 v% j
                        b1[jj] = vec1[jj];7 c& q# a& }6 y: m; U& @0 z
                }
  d4 A* G6 W0 b" h9 k$ Y$ E' [
1 N6 |5 W- d& D2 j1 @5 Z                for (size_t jj = 0; jj < vec2.size(); jj++)
. k& t6 t/ P# l/ q0 E. {                {) z. K+ V2 P1 m# ^/ R
                        b2[jj] = vec2[jj];4 P% ?6 b7 j8 w: I' i
                }; N7 }3 Q5 g1 b

/ X+ \# [+ f/ j$ u& H" m0 J                //Method - 1  N=100000 247s  " E$ D- c# i/ \2 P. O7 b
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);  `+ S- R2 z' x4 j
                                
/ ^. i* ^' S  I0 C+ a/ ~                //Method - 2  N=100000  237s
+ U" F, N$ N5 w+ P: l                /*
9 m1 [, d/ Q$ y                for (int jj = 0; jj < N ; jj++)% i; y3 e2 ^* @
                {% L! `! D0 q& B7 R
                        fresult += vec1[jj] * vec2[jj];
! H8 V) k2 U- B; A% |0 Q                }
3 p: q8 N3 I2 M1 G% \4 n                */) H5 X1 }  w8 b2 _' I4 E
                                3 `  f4 Q7 \9 v( ~/ _8 Y" X! H
                //Method - 3  N=100000 204s  @6 Y9 o, N% N
                /** r3 d# O  W1 R
                for (int jj = 0; jj < N; jj++)
: q: O- Q1 Y" W, R, }                {7 O0 m2 X& Z2 t2 N1 [
                        fresult += b1[jj] * b2[jj];
) Q$ H' P$ W6 b5 B: j( o                }
" C/ w. k5 o. E                */
0 j$ c1 @: w/ ?6 k$ m' m  l' i
4 e% {: f4 L/ J. `; \0 t                //Method - 4   202s$ v# v6 x& O* J" N7 Y
                /*
# m, Z% F9 s8 Q& M                for (int jj = 0; jj < N; jj++)
+ v. o1 b) q$ Q0 x) l6 E# d' u                {
( k; ]: E+ ^4 v                        
/ q4 ]/ j8 b/ e& O8 ^4 R# a                }+ }7 }- ^1 i: z6 z) G4 G$ _
                */; s0 j1 r' G. B! T1 y. W* N( G
                //comment out all methods, N=100000  202s                5 c% h& N+ l) y2 d5 e  V) K- E
        }+ Y: ]. P6 {1 p1 K8 \; D) z2 W! u2 y
$ n9 K& D- P9 [* }1 k/ W
        delete []b1;
( b- f9 u0 [3 {  y! z) H6 i2 l        delete []b2;
  N, t  L  w. d+ ~5 e

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
0 H  a% K$ E; [/ M; Q+ W5 l6 y# N5 n# S
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?0 K/ U# n9 m, ]9 Z

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15  S( u0 g) E) G5 \7 o$ W- U
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?7 R$ [6 M# d) a1 T
2 ~  u# [' a( C4 D" F
你第二个试验里面的j在循环里面又重新定义 ...
; P1 C! `4 F7 d: `7 p+ L
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
# `3 f  b+ s/ r% ^% F) d7 e2 H* }- ^- `1 @( P6 P  f* K% ?/ n/ R# j
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
5 y$ O; E0 Z/ L7 ?/ v9 r/ U内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL9 |$ B2 b5 O  K3 W1 N( t; X

$ [2 H# q+ j: T3 a3 n; c4 X" H不和它 ...
6 m  ~; A+ G2 I# Z. k
5 M) T1 ^' J# J! v2 `9 P2 Y' C& t8 o
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
8 ~! M% N" e2 c, H& W( n. T后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
3 V) p# [9 l( }$ @3 kvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( z' q" j3 d" l6 W" H! }* e# e{
: e1 o4 {% I! a: u% x% t        comp temp, xtimesy;
3 e# m- t9 a$ R+ m$ s( x$ v$ ]
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。4 ^' z5 Y* y( h# N9 e) L
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
# _" F% {" |1 z8 y; T6 xVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
+ F' V) C9 Y( {' T' K  n* y理了理思路,重新做了一个测试。0 x5 k  S- \/ W+ s! U4 R; _
做了两个 vector 和 两个 float *, 都长 100000% f. u1 I( C0 m4 r' l% t. r
外循环 6000,里面先做随 ...
. d/ g1 h/ h8 M8 P) i7 L
这个时间是从哪里开始算的?
. f; ~/ a8 |, A1 R, g: U  }我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
: _4 C9 b3 h2 L! d8 J+ c按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
6 V) V& w1 h. s2 Z; `6 e0 J( Y) K这个时间是从哪里开始算的?3 R; S" {7 r# W$ R
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
$ L7 J) o/ q0 Q3 }( i9 r
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。) j5 _2 \4 M' ?2 A8 ?
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
5 U6 V# M/ C. c" }* {# V与此对应用数组(指针)花了2S; a. h- T. t: P0 O
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54( }$ ]2 i" L4 g7 L9 V
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 n% |& m; V: R& Y- H1 ?
{
3 N& E5 R& w/ ~' D) l+ x! k        comp temp, xtimesy;
' Y, ~% v+ p- r* p3 Z7 ^! q4 G
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗2 D& V+ j7 f0 g) u: T
! T% e; c* X/ h' R+ F" a  [

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29# c( Z6 [8 }4 @3 U/ n* {
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗/ W4 y! c9 W& J0 b3 i

- L) ~! Q7 A. \8 M8 f, W ...

: _4 l3 T4 k7 e你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。+ d% Z( M3 N: \6 T! G+ W
; w. o  h& h. L2 X2 ^" a2 q# d
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 # B5 d5 Q  W4 {' Q: a- O1 y) e
  a/ ?) n4 h( _% F% Y2 o8 |, F
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
0 M: h( \2 a5 H有空时我会试试 SIMD和并行,看看能提高多少。/ Q1 T' D  [( E& @' N
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
' r, i, Z" `8 `+ x. l$ |$ N: k谢谢大家的讨论,I learded a lot.  红包已发  
, e7 b: ~" Q  u/ p0 N! G
" J/ b9 `5 y* q) z" f2 R3 T% L. S2 @0 g% _

, `/ N1 J  `8 B: G3 c& G
: @& k( G: s6 {/ `; p* K" w/ G




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