爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
, [* N, Q$ @7 n7 |( g: F+ g' h. C- H0 S
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。% I2 `2 o9 i% a# \3 B. e
* A- r0 E+ l2 p( r+ R' C
速度优化问题真的很有意思啊。5 i4 N0 a; X- n7 {. {
. y6 s$ j( x+ @; s2 j
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?. q) X( p8 ~9 }6 y+ ]' {
把代码贴上来看看?
( ]# N+ z8 z/ p  o6 D! x! f, u6 S* k: l9 g
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 8 w7 p" F) C$ A& }/ e
数值分析 发表于 2022-9-24 23:04
5 |9 B9 S* X3 B' L( [拉下来?拉多少?
) v& ^+ s+ |* `9 L把代码贴上来看看?
3 F, `# W1 y* q6 t
: u% T! }) k0 S( I& m0 Q
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
3 U+ d8 J8 U  {0 d  `) d) X: z{$ }6 O# \! ~# h" W' `( V
        comp temp, xtimesy;4 [$ V. T1 T' w; ]" E
        xtimesy.re = 0;
2 w$ T5 ]9 v7 y: T* G: t, n        xtimesy.im = 0;
! W' T: N! ^* P4 t6 v        int j0 = lenB - 1;. K+ _# T( J3 ~$ i; \
        int    i, j, i1, reali;. t! M) |2 K( |
        if (lenA % 2 == 1)6 @/ H" O7 y' _6 [1 u
                reali = lenA + 1;
' N9 l( w6 B8 w. m  j  M/ z        else
( \6 f8 `( q$ d9 o) j9 m! c! N" ?* _                reali = lenA;# h) @. C7 I% O, @$ A3 r
        reali /= 2;
3 `3 W# K4 {# |# a  Z
6 s) G, H  j. z' b; K1 E; j3 ]        int nconv = reali + lenB;, z& a. U( F5 H. r
        //#pragma omp parallel for: s4 s/ f) k$ ?3 F7 p) |6 a$ H
        for (i = reali; i < nconv; i++)) C( O' P: L& m# ~
        {
. f/ `% P; Q* z* H! ^  d- \9 `                temp.re = 0;3 M+ h0 p* s5 F8 R3 ^0 C- r4 m
                temp.im = 0;( Y0 I/ J* i0 S
                i1 = i;& }/ B! l  l  H% c6 a/ F9 x/ d* {
                for (j = j0; j >= 0; j--)0 m# p; l" F: W7 g
                {
9 L* Z& S, R) z% O                        /* floating date operation */
+ T& h% C0 S- g3 z                }

+ G7 ^* F4 F* i, T1 L! i        }
$ T! }% N9 u' m6 R1 O9 O}
$ ?  y! O7 \) x1 g- b4 W. U- b$ H
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
9 C* c4 [$ y/ B6 t* S: e) y. x7 `
. w) y. `. p& d% M0 g红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。8 K, g: J  n6 K$ V
现在call xcorr 100次,耗时78s.
1 D: L. K  m# F) q  J% a3 e9 d
2 t) e6 u7 F1 r. S如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. " i) P" h4 W8 D5 U

) X% s3 N; E- C6 `
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
+ Y+ K- O: @# ~Maybe Debug mode?

: ?: v5 y$ O7 s  F
/ B% Y  f! C2 ~- ^! A不应该,看我上面的回复。1 {5 \* }3 e4 B% t# v3 \1 B: b6 P! h
& z* O" V4 A4 k: z3 T
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 5 Q% @/ }8 {8 n1 e; t# a5 E
雷达 发表于 2022-9-24 23:547 N$ E- @) x1 X
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" J6 a' p1 ~  I/ `; U
{1 L0 p. @% \) b1 z5 x& ~
        comp temp, xtimesy;
! p, z0 a& N. K2 F( U- I8 J

5 D% I) H' [' c# ~这个不是这么比的吧。。。
7 R* j0 F+ c2 ]9 Z5 n
* v( I; v/ r2 {! c  H您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。0 g' x. f! n; z$ g8 ~9 g* x

# y5 o$ O8 r! c2 s而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 + S, t+ \& P' N: n, f' W
数值分析 发表于 2022-9-25 00:20
' e, v* e3 E% f3 u3 t! G! B8 f1 n这个不是这么比的吧。。。
; \0 c8 h8 A1 u2 P; W7 {
! d. t$ f2 S1 |6 |% v( o您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
* q! c$ ?. Q( n
, j- O: I; M+ T0 I1 y6 D
有道理。
' }$ n  Y! Y0 w! d; ^3 D所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
( o: i# _" P& z9 h, i( W1 a9 l) X' Z, `9 T9 N0 g8 x) i
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
# K5 r/ s- M7 Z* @有道理。. y4 i6 z6 C& K  c
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
* U& g6 W0 q( X6 P  Y) F5 ?3 M
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多* B) m9 W. p$ ^* O% B2 J! c/ n7 t, l
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
( I3 X& I9 B1 {3 v5 Q这个不是这么比的吧。。。  K2 _- m' j* ?0 u4 Z& w. \, K
+ {# T) J" t# n! v& e2 }( N
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

! X9 v" Q& V5 ?% v, o$ z0 E2 T- Z4 {' T$ I; h
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑   h" c" z! S/ Z$ w: b6 {( u, g
沉宝 发表于 2022-9-25 01:48' Y" }7 n  U0 ^3 H- s6 Q/ |
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

+ Q5 c* L/ C* c% ~
( s8 T4 M) _5 S. q/ w+ a是的,兄台说的对。7 ]; B7 c0 v4 F  S- l" R: @! ?

3 }8 I: ~( A: j9 Y- h# n# n其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。3 L: W2 y, X) a" L" K) R) c# K

( W" g. s$ C5 n" a0 q雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
) @$ s# [5 h5 j3 [$ L0 H6 K7 Q7 M/ {- D* g- T: P/ M
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。, i1 ]8 z6 o4 [7 q- B
# \" y1 {, N( P* w; L
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 1 k/ Z) x* i' }- {
沉宝 发表于 2022-9-25 01:27/ r3 L# `3 l. K8 B
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
5 f9 Q' K9 R. h! X8 n% E' k0 q: f

% z/ J" o; z% g: I3 a7 M又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。) r5 d9 d( Y% E9 W6 Q1 ~3 I
- x' \3 V# G) Q! D/ D( i
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
# a& e! R% T! Y% l; b+ g又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

- r/ B) h& Q' U时间差一倍的结果可以接受。! R( Z# d! U; I  s/ F  t

# K; r/ S+ j, e8 o7 \: g4 D9 p你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
2 x* f7 h5 o4 K5 q) n+ G& x! M0 o
雷达 发表于 2022-9-25 04:47
: O. {5 l+ e" H, ~' c: }又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

+ W: _5 N4 g' C( F
7 v' Y5 \* T1 n2 ^# _( f0 k* j! @- f# b+ o, B! Z" P
) |; [/ q, S+ t. o) V5 s
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
/ Z0 o! y) b' C8 k1 R+ E5 A
数值分析 发表于 2022-9-25 14:58
# b- w. ?/ t8 t  `能不能把这个也贴上来,看看和上一个有什么不同?
- J% k* |( M# S! E9 `/ {
理了理思路,重新做了一个测试。  i8 k2 _5 m6 ~5 L5 G" m4 [7 d
做了两个 vector 和 两个 float *, 都长 100000
4 _* p7 d4 J% F6 b6 b外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
4 E7 W* H& @3 l. k4 g2 A; o" D5 ^
内循环试了4种方法,
" V2 I: w* F' `& r1. 直接调用 vector inner_product 247s
1 ?; h5 D( J# Q1 Z$ d! n6 h! B* C2. vector 循环点乘累加 237s
! o. k* p5 j$ F9 s3. float * 循环点乘累加 204s
: t; k1 ]9 j" e7 v' _# Z% f4 R+ o4. 空循环 100000 次 202s/ u8 a, K; s8 X3 B' a
) I: _! S' c2 ^
不做内循环 200s8 |6 a( {0 @7 S5 f+ Q
$ Y* z3 `& _6 c! o; N# V( `
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
# r1 _3 `- Z8 ]: a# D% L; ?' \$ D# u另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。8 r: B! }/ A+ `$ M" {
: O. f$ a+ y* p: S' z6 S
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
9 V' ?6 f2 ^' ~4 W' [* u) J( u$ G3 L: b# X' n8 m; N
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
& S. A1 H, T' P9 u% V
; B+ z  w- D0 z* I) P8 E
        std::vector < float > vec1(N);
7 J( w" {$ \1 O* Z        std::vector < float > vec2(N);
2 s9 ]/ C% _" n( m6 }9 X, j        float* b1 = new float[N];" D# ?7 G7 D# U
        float* b2 = new float[N];
9 ~! ]/ \3 A& r  r8 J1 B% ?1 `* E$ s# Q8 l- R, R
        for (int j = 0; j < 6000; j++)6 T, e; l  ]6 w. t5 v* e
        {* M8 Q- w9 s1 j/ h
                std::generate(vec1.begin(), vec1.end(), []() {
' E% w6 q7 r5 v8 y/ x, d; a                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;3 F. f2 Q! V; h) ~3 M
                        });
3 _, A5 e/ r7 i' p/ u# m2 B+ v4 @. }1 [. s0 K/ }9 ]* n
                std::generate(vec2.begin(), vec2.end(), []() {
* K3 Y8 M' h) s" c0 @7 T) L                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;( I0 o- J/ D# _" ], r. W
                        });& t  [. A- x' t9 n( t' H

. A" _. R' D: @" h0 D0 L& w                for (size_t jj = 0; jj < vec1.size(); jj++)
" j- d. K6 i( O, B                {
3 q- N! c1 [, Z                        b1[jj] = vec1[jj];7 z- Y$ j7 q# c( T  _& Y
                }
- p2 a+ J5 G+ s7 U% H/ t
" _# C4 m/ }4 |9 n8 |                for (size_t jj = 0; jj < vec2.size(); jj++)7 j5 U& K+ \/ h$ o1 F3 U8 g
                {4 h' f  {1 p0 g% D$ s! w2 n
                        b2[jj] = vec2[jj];
  O4 O5 v: {+ @) Q                }
( F4 \* B3 o. n. u! m) ]3 s  j
; V& _" J7 C* z2 H+ E7 X1 k" P2 F, V                //Method - 1  N=100000 247s  
( q" Y4 e7 z6 f3 x! [7 b9 m- p5 z. D                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
4 i. p. V7 L- P" Q                                
9 w" A3 ]! V5 f! ~1 H4 c6 I                //Method - 2  N=100000  237s/ O1 {/ Y( ]* d% T1 f
                /*
  G3 D9 s, x" {' B6 M: Z/ E                for (int jj = 0; jj < N ; jj++)0 `8 u! v2 k6 t. c
                {
) `5 q" _1 {+ g9 }5 k( w                        fresult += vec1[jj] * vec2[jj];5 L3 i. V* f7 D) Q" S9 o4 u  {
                }7 @( d7 t# @5 B  s
                */
! w- Q8 \3 a6 l' I8 Q; }                                
$ `4 U- @7 b* Z# Q/ L                //Method - 3  N=100000 204s# f7 [: }3 [& K, P7 ~% ?
                /*
" y, t% ^, A1 w$ x/ ~( B                for (int jj = 0; jj < N; jj++)" E, T: ?7 `+ e
                {
% x. N. k" T7 L; X5 p6 O& @' d. U                        fresult += b1[jj] * b2[jj];1 P% K; m* o6 ?  L. B6 b
                }
# |1 X3 x6 W( B* h                */' k4 E3 `! W) W0 }
7 S3 {1 S5 Q' y* D( S
                //Method - 4   202s. D3 O4 q7 {4 `( ~4 \9 N9 T6 K
                /*
! E1 d/ S* \* p6 n                for (int jj = 0; jj < N; jj++)& s# \3 \/ a# s  K. G# {
                {" V) z( G- [4 r, J3 w
                        : e9 H9 h- O/ k( H; Y* L+ O, y4 O
                }
4 J& o' Z6 e, u                */. Z, J: d$ F" d
                //comment out all methods, N=100000  202s               
9 P2 c5 E! {, H9 E( R" r        }
. E" u; l1 O7 N/ Y
) r$ c( W$ A, a) _8 g; R        delete []b1;- S; V- O' P& ^4 H, n! p6 h  P
        delete []b2;

9 f3 p9 Y+ `2 D3 V, G, C- j9 k
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
7 q2 U6 `' u& |5 n: [% C, U9 O
: c2 |2 F6 A# X1 {+ e  d0 y/ F; y% P你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
( \8 P& Z! L3 R8 Q' y
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:159 {+ d  x! V- t) P9 |
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?  U: p, A! L& F' O* D

5 }. S) s7 ]! H- U) u你第二个试验里面的j在循环里面又重新定义 ...

% |! _: ?# k6 R2 I3 ]8 D内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL, @9 h" V: @2 x. ~

/ [' y! k% t% |1 S3 A5 ?' U  Z) w不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16# K% t( Z) G& v2 l% a# d- C: f
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
; L  Y, F; E+ |" Q
- e# h1 W) o& u0 L不和它 ...

* d0 V/ _: ~, A5 x0 Z3 {3 B1 S. i+ k! _5 H$ q+ m9 g
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
5 P2 O% w, ^  |* i8 s( Q后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
! n8 W2 M0 e0 D3 V0 F# Hvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)5 p$ o9 Z; O" Q7 k
{$ M$ @3 b4 E) a' Y; `% {
        comp temp, xtimesy;

/ K& n+ I+ P( l8 Y. c: c这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
9 k4 a; e! F7 D& ?% C内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?, v6 B9 {* z! S
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30" O* l, O& U& N* I: G& O, t
理了理思路,重新做了一个测试。( r" J# w1 S$ X
做了两个 vector 和 两个 float *, 都长 100000
5 ^3 N* z5 ]' z, t: z$ c外循环 6000,里面先做随 ...
. S) x. Y1 ?2 R5 w2 x2 E$ W$ ~+ M
这个时间是从哪里开始算的?/ m+ d8 b, B7 b
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。+ V/ H  D: l9 t5 i- s* M! @7 S
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39! b6 E7 J* f. g1 z! g. p
这个时间是从哪里开始算的?1 ^2 V) g$ P0 n3 l' I6 G2 S" B$ M- m7 [
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
* l; E' O9 d: Z
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。2 X' d) q5 ?* \6 L5 T
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。0 N( b* j* z* J8 l7 {% j- |0 W! Y" M1 }
与此对应用数组(指针)花了2S6 ^/ ]; u# h4 ~# X( ?, j
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
- O# S+ Y6 e  V$ @void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
: x$ b) S5 t; k. D+ H+ J8 z5 M! M{
  a( Y: [& e  d, V/ x        comp temp, xtimesy;

8 L6 V+ G6 K. s8 c5 }& s我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
' U3 }& p) j7 ^5 G% ?9 f1 ]- ]( p8 L  b8 R  y; k- |3 p$ t

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29, j4 @, R. F2 P; N: H% O
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗; G5 S  a  D1 p0 F" a
* M/ D1 F* \9 C4 d" h
...
$ |, [6 u7 S! X! \) |
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
0 `  x1 f* Y- J6 D% g/ t: N" o) i1 H# q+ |8 c! o8 Q+ _
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 ' Z3 e: {- p0 W, n, v* T' ~

6 w  x0 ~/ [! b5 q# n+ g! H是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。( C1 P; k% s1 X" X! B7 l9 E
有空时我会试试 SIMD和并行,看看能提高多少。( ^! q# H. h( K. G4 k) Z1 w
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 " q6 D9 f5 Q# D
谢谢大家的讨论,I learded a lot.  红包已发  
9 _6 h3 x9 Y+ p( B* \
, p( F8 Q. |1 |  K3 F& W% i/ R0 M% x0 @& A; Y. b: \0 F

2 f' f2 F! o: o& b7 w2 _( j7 x' ~3 O8 Q) n( o+ k





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