爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?, S9 X: Q! e0 p/ H" a, a# b& F

; w; U! j' [4 V# t" Y6 ]0 \1 Q自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
2 ~6 V; U7 b4 n# r8 r" D
9 c% b) |1 Z+ k) V8 {+ j3 W4 k速度优化问题真的很有意思啊。/ {' M& r$ l( C! C, U# S
7 y' F$ r! }  B9 ^; f% j. _6 r' Z
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?4 K$ ?& x' H5 [* }
把代码贴上来看看?! n0 v- @9 c9 y* F$ u: k4 Z- L
" X+ e' R  }' R) o6 Z. W
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 - c, [' p3 j/ x0 \9 H
数值分析 发表于 2022-9-24 23:04: `6 Z4 l+ u7 o: f* w/ {& c8 \- [
拉下来?拉多少?
( Q0 r$ |! b2 c0 \  r) Y+ X把代码贴上来看看?

0 f6 Z2 S; ]6 R( Y8 }: g# C" G; P% p; Y( b) N7 }, l
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)& T3 o' [- g" g3 F: Q
{
; Z+ T( W, ]" k& I. r* \        comp temp, xtimesy;+ `" t5 A9 h% _2 h& u( |% x! j
        xtimesy.re = 0;) l2 W0 d4 q1 E, s
        xtimesy.im = 0;
. b' \7 Y9 r7 q$ e        int j0 = lenB - 1;5 U9 d* R% B- S4 U! `
        int    i, j, i1, reali;7 F! Y) o% H' B/ s/ M2 k6 X* X
        if (lenA % 2 == 1)
+ T: _8 W3 Z  }" E/ D/ f% D                reali = lenA + 1;+ P9 |5 {4 |1 _9 x
        else
# g. z: x# G' C9 p                reali = lenA;; v3 {' s6 b7 N
        reali /= 2;
! V: ?0 B/ ]3 b7 H# f& |2 M6 W% E# D$ J* z6 t% n3 H
        int nconv = reali + lenB;; F! g8 q" [; a+ z% d  g1 M% v
        //#pragma omp parallel for% {4 J- f0 B# ^. N2 p) a
        for (i = reali; i < nconv; i++). |/ q  U( r+ E2 ]8 o
        {5 W! N8 f) D: f5 |8 Y2 V
                temp.re = 0;
) V+ O: Y# e7 B- L1 H                temp.im = 0;0 _& y; n- U! u4 O+ |. J
                i1 = i;9 y5 ?. ~# a' z8 j7 R
                for (j = j0; j >= 0; j--). U" `3 g+ H; U. r! l* @+ q9 O
                {" u' q0 g( j  H
                        /* floating date operation */7 P; w& ^0 [$ @8 A* [0 V: d: u
                }
" \- U+ v" r  j8 d- o+ W2 V
        }
9 s9 c) R3 u0 ^2 c0 |}( i' y, |0 o0 F. M# [

* x& p( x% z- Z5 ?+ |- B" Bxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样  c2 d' t: x+ i' n" L

/ v) i& u* f9 v! f, J红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
1 G' x0 i2 a8 I现在call xcorr 100次,耗时78s.
6 c3 a: a2 z! P8 i* K+ {9 R2 @" `3 V
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. * V# a  [/ R% }) U% l$ V9 {
0 {" `' S- w) ]1 g3 x4 H) R" T

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33* J/ }) @8 x2 f* D; S0 t3 c" k
Maybe Debug mode?

. R8 o4 M7 W* v9 a2 D, _$ b: H1 B6 i/ S) E% ~
不应该,看我上面的回复。8 J& ?5 \' m; O  Z, `" w
" ~4 y: e* @. ~) p. |8 v2 P
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 - y! H/ W, b, `' l
雷达 发表于 2022-9-24 23:54' t# I5 W3 H. s  c* _1 L3 E1 `" A
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) Y, n: X  ^8 a' m2 ~; K5 R{# T6 t8 O6 l/ s( ?) S3 r+ n, ^7 x
        comp temp, xtimesy;

4 N/ M+ A0 v5 H; s  v" q
) k3 u" A, _1 C9 H6 d$ b9 Z: V" t+ R这个不是这么比的吧。。。2 X' Q& f5 ^0 j5 ?  R1 w% W
" _7 r7 J. j4 j+ I0 P# T4 D
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
' V- b8 q- Y7 k* B$ |0 W8 J/ D$ u5 H2 o. F
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 % E- v1 k' d) D2 Q3 E: O  D6 n
数值分析 发表于 2022-9-25 00:20
: K4 V+ ]( G$ ~: y$ B) c  A这个不是这么比的吧。。。8 @2 g  d0 J! t1 B- f
( x4 x( V9 X! g) b) B' o0 Y
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

1 r+ s9 a, k) z0 V3 Q* ?8 ?5 U$ P4 x6 ]0 H$ K
有道理。
; Z- d. j! b1 S所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。, V. [9 P/ Q8 f$ c" R( @
  o! w) Z+ U8 v8 O4 m* `- L+ P0 T
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46) V2 n5 {/ e' h% ^- N! L, |1 l
有道理。$ W2 [: f# T7 Q+ V6 `. M) k
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
/ z- v, n. N0 `2 f8 {
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多  E$ l* |+ |- x. f! r7 r( n, i
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20' r% n" S0 O5 ]8 s& e! V# ~
这个不是这么比的吧。。。
2 w) s( R, n: l& L. Z) G& P5 ]% n  p/ l) O0 c& ?  |* H$ w
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

3 q5 D* j  h0 d" s) j
( U$ s$ Q3 p4 J7 K* z, W现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 & k6 W2 y5 H9 H, p8 z
沉宝 发表于 2022-9-25 01:48  t6 t6 v4 u( k0 m$ c
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

" ~, e: a5 O7 V1 L) J
& j+ `1 A- M) v是的,兄台说的对。
+ ^5 L( V' P4 H2 N. m/ E/ g, A- h' m9 X( \7 S  _
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
  ^  o* [  \# [2 K3 R- Z, ~" a2 c% U0 H9 G
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
8 {- Y" {6 n& I# W8 O9 B$ ]' ]  M
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
& F# h/ z: ^( _, @; X! H) z' p; h+ n+ m" A7 S
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
* ~( J3 s- w% M# M
沉宝 发表于 2022-9-25 01:27. B1 S, P  X3 i8 W3 q( X! q2 |( `
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

0 W+ B: u+ i7 [- V1 S
# r* [  f1 y" u又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
( F7 ~% F- e8 M1 z1 a5 Y- q, o
* |1 f1 k& v" w6 z% `5 }: H1 v4 J我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
8 V1 g* Q' f+ G# B- I& h又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

: W8 `" @) j/ D- r& B5 |! M+ j时间差一倍的结果可以接受。
3 e2 q6 \/ M2 @- T  R+ m" e' v2 ^; h" E1 t9 B- ]# h
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 - e, B" |3 [. v" C
雷达 发表于 2022-9-25 04:47, X( y) I4 j& I& k1 x" g/ O& F$ @
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
9 Q4 z" {( v2 g: p6 O( }- B) l2 _0 @

# Y1 d& B/ t, L( m; q# `* f* i5 D+ d5 x( ^" q% _5 I1 S! u
, x0 y* Z, s, I  F
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 $ o, L6 M9 X2 c( j
数值分析 发表于 2022-9-25 14:582 W8 K3 Y3 q- B. x4 A, j
能不能把这个也贴上来,看看和上一个有什么不同?
! O  l7 X! P4 o* O
理了理思路,重新做了一个测试。) n& r3 Z! Y5 `4 W. \' b
做了两个 vector 和 两个 float *, 都长 1000004 G7 R' ], L1 I& p
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
! s- h8 o2 Q  U) I7 s1 B7 ]4 P/ q& \) H* J8 y% K6 r( D* G
内循环试了4种方法,. C% u3 q9 W' Q# r, ~3 ^  n
1. 直接调用 vector inner_product 247s ( d  l+ f4 ^5 @" v( A6 X
2. vector 循环点乘累加 237s( Q+ F% ~* S* s3 c/ @
3. float * 循环点乘累加 204s0 f8 T' _% _6 w* ]
4. 空循环 100000 次 202s
; y  Q  I' q* I4 q3 T4 ?' h/ D: b0 r. S+ G4 X' |
不做内循环 200s
/ n! e( ]9 }- P% @2 d
% @: H# X3 W3 Y* t1 ~7 X4 ^你昨天说的对,内循环本身占比是很小的,大头在其他处理。
3 h+ L  ]) `8 {4 h) J3 u另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
: Y6 x- s* ?0 t! }- a; E* s
3 d% [, D7 ]0 {) D5 U至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)$ d; f; g; f" G* J: {% b0 z
7 u. ~  h4 \# }% F4 \, x
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
. d4 [. s" k0 w" I  y4 N0 D
- ^3 B7 E% ~  v7 A! v5 q) v" j0 D9 V
        std::vector < float > vec1(N);3 |* O# a3 }6 g) S0 a
        std::vector < float > vec2(N);
3 H! ?' f8 z' f  D3 Q/ S        float* b1 = new float[N];0 [  o9 v# @( F9 l5 t! c
        float* b2 = new float[N];
" a' S" l5 ~* l/ B( x* W$ v1 a
9 o1 p: J; b7 d9 I: {" Y( r        for (int j = 0; j < 6000; j++)
8 ]' J' W, J6 ]        {! \1 ?5 s2 ^. }5 M( v! T1 L
                std::generate(vec1.begin(), vec1.end(), []() {
" Z3 y: g% w- ?. l+ D                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;4 L, n) ~* W8 I4 X
                        });
3 i. f5 H1 n) l) V6 v% V2 ]1 n/ z! g6 d" J
                std::generate(vec2.begin(), vec2.end(), []() {
- k6 y* T4 ~9 v, ?! S- ?" v# n                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
: K, \6 i- @) A# B* q                        });
% m$ q! y+ r0 G/ o: y* J0 e9 \  Z3 u. {5 h9 y7 Z8 F, n2 H/ R5 q, [
                for (size_t jj = 0; jj < vec1.size(); jj++)/ x5 B! t) ~* p5 i+ k
                {
1 y4 H8 |" r, a' B" \                        b1[jj] = vec1[jj];
) y# Z: g8 x' c                }
- S+ h# ^4 G8 w" P# w- Q& W9 q  q$ _# \. y/ ^7 M4 Y
                for (size_t jj = 0; jj < vec2.size(); jj++)! s( L2 `, s, ]; u5 w% G, B
                {! U/ y7 f: K% D7 [' y- r! c
                        b2[jj] = vec2[jj];
, a% m& W' s  a% C                }
- c! A* z6 k# O3 ~( K3 l$ {: c- B, c( D
                //Method - 1  N=100000 247s  
, ^  x7 A# b  w8 h+ r  N2 J! l4 p' C                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);# n- ?/ M3 N- S
                                * |7 ?) K8 n- j* |
                //Method - 2  N=100000  237s
! q5 _4 p7 z8 B, k) _                /** g  T6 M5 V( F9 [
                for (int jj = 0; jj < N ; jj++)# b# M* K+ p6 e
                {1 t# B+ i) s/ E* e. Q: w2 G
                        fresult += vec1[jj] * vec2[jj];
) u' K' t% ~" z7 }( {                }* w# {  O+ C# v2 z& j# D2 `
                */8 K# }) z3 }8 f9 W( e
                                5 w! `8 p, P) L# |' w8 K
                //Method - 3  N=100000 204s
3 w: ]2 K: ~- b' I# E                /*
1 q5 h( {9 q7 B0 ]5 l+ c                for (int jj = 0; jj < N; jj++)- _6 [+ c0 r2 v0 \, j  T- M+ |
                {
; C8 E8 V) t, j9 b- T                        fresult += b1[jj] * b2[jj];
3 m/ s$ p' p9 t* ~                }9 Y  b: e. K- T8 k; A) @8 c( S
                */" Y5 o7 n% b* J( t! t& A& f" r

# W# `: }, l& r5 E3 r8 B) d$ H/ M% n                //Method - 4   202s5 J3 V- t& z- E% b3 B
                /*
6 r% f& C0 k3 B                for (int jj = 0; jj < N; jj++)
( R) D+ I: P  R. Y, ?+ ~$ }                {/ {1 c+ O. e6 K7 c5 S
                        + c* [( ?# m+ ~9 ]
                }( a& T6 F3 ^2 P% c1 s9 R' S
                */3 k, z$ G" H. v4 h' l7 {9 T
                //comment out all methods, N=100000  202s               
/ m  x# K6 [, [# c        }, P/ r! d0 _/ L/ [- k+ A- A
( n/ E/ P  B7 B# {5 }3 D
        delete []b1;$ |  ?; c7 m- t, w2 y/ v
        delete []b2;
' S1 @+ u2 H9 y, r2 ]4 ?  S: ~/ w

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
/ I; [4 C. O; Z% v+ l
: e8 S" L" G3 ]' r+ g, K7 w你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?2 V$ ~/ {1 c0 z; h9 [" [

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
0 H5 x' [' V3 b2 z瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
! p4 ?( V5 o( P, M% J$ N3 E% Q2 M% w+ }$ y8 a5 W
你第二个试验里面的j在循环里面又重新定义 ...

" Y/ j. I  z! R( P. Q内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL3 ?+ t8 w5 L& S: u
2 S8 a) J9 R6 S* F* A) ]% x* G2 l
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
' w2 E3 ?# _. Z) P, p6 p内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. G2 G6 e8 F# a  Z
- \0 i& [5 G9 e6 \  ?1 T- |
不和它 ...
% H  }: v$ ]9 V  V
9 a+ l2 F+ ]: k9 m9 k8 g* U
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。/ s" O! Z8 {) ?9 O1 f2 O
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54- c& C& _% Q+ S5 m5 \( }
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
/ p$ B+ s8 l8 Y. J) _{
5 p9 K* @0 G, y+ W9 p" c        comp temp, xtimesy;
( S: c9 U) P( b
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
9 Y! M" ~" w9 Y) K  _: V& m0 X: ~内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?' t) I' @& R" S$ o  _
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
, v$ D# N5 p# a1 @理了理思路,重新做了一个测试。4 V0 s; o2 o0 q. X& J
做了两个 vector 和 两个 float *, 都长 100000
: c5 J' ~* D8 X6 ]1 |( Q/ E3 x外循环 6000,里面先做随 ...
- M4 g- {$ K$ b: d& C$ M) [, m) d
这个时间是从哪里开始算的?4 F+ j4 q- _$ t% G  Q/ K, C
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。8 a" M3 R/ T" c0 \+ p- K
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
/ {* z$ D+ l4 {2 }% |- r" D这个时间是从哪里开始算的?
) q& X2 U0 {4 s+ ^我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

# {2 b0 ]! ]* Y$ \我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
; @' n6 V8 w7 v. p5 J" H* q你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。+ N" w8 ^# P+ P1 T3 m8 P
与此对应用数组(指针)花了2S- y. C4 }" r* \, U  A
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
9 `  K' _9 M2 A3 a" d$ r4 {9 Vvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)# X% F% S" c4 B7 v0 N' W
{
; e: n; u( }; e' A        comp temp, xtimesy;

2 l0 U9 m. Z: e+ I) D9 D我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗+ t8 N3 R" l! \+ h. ^  j
7 `8 I! X4 e% }) r* h! V

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
8 c; w: ]* [- m; ~* F我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗# j0 A( ]* [) H% W  b7 y/ s) b
7 q: x. C1 {) u: C
...
% _2 v. J7 R+ z) I: \
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
' |% P& P5 \$ z# J, L0 |; V1 E
2 ^* {* u3 H$ }8 J! R, M雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 : D( j/ D- j8 J# @

1 b& e3 \7 W* T% r( h+ y是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
+ Y' t; ^/ X% i, h: {% T/ F有空时我会试试 SIMD和并行,看看能提高多少。
+ E, n0 e. s' Z4 P6 J* N: [5 O过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。9 K9 A/ u" q9 Y2 O8 G, ^
谢谢大家的讨论,I learded a lot.  红包已发  / w/ [8 ?* J4 C8 Q; h: v$ b, K6 U
6 s. {7 m4 ?- R3 p
9 i( R, i0 v1 \8 `( W
; O' e; U* B; H6 }

4 j! S6 A& D3 M. U6 ]1 G




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