爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
( Q8 S# F1 s( B/ y
! I! P1 O! f  f' S! J; q4 g自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
" M0 e7 N" g1 z5 |: L) E6 P0 Y. [* h+ u1 }8 \. w  e
速度优化问题真的很有意思啊。
$ k+ u4 x, o) r8 x' ^) V7 a  X1 o3 J* J$ A+ Z1 v
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?: G) E, v) }0 G* c4 I- ~
把代码贴上来看看?; v4 @6 ]7 \3 j; U4 {! x  c

; B& X: h3 b9 j, ~1 E1 ]  |: Z难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
. X& x; ^+ C0 m0 P
数值分析 发表于 2022-9-24 23:04* c* A6 {* G! D
拉下来?拉多少?
9 ?0 n- q, a9 I' }4 Z把代码贴上来看看?

7 C' w& d, R% F9 }  e/ F% W) W# ?: {+ l
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 M2 D9 h& n; [6 q
{
3 k! ]/ Y  R% s. G* j        comp temp, xtimesy;
  \$ |$ _: b# S* M/ Y3 Q, q        xtimesy.re = 0;; j6 q! C% p3 n% o# m6 y5 C9 d8 {5 p
        xtimesy.im = 0;9 O6 w. ]( N* F/ A/ p5 @% |
        int j0 = lenB - 1;
' X2 a$ h+ ^5 C3 P1 R        int    i, j, i1, reali;6 M2 D1 v( Z* }$ M8 ~- q4 c
        if (lenA % 2 == 1)
+ t1 ?8 }" J* R4 c+ ?! M! [                reali = lenA + 1;$ c# r$ m, ]; u+ J* Z  `# f) }) v
        else( {5 T* h4 k0 ^# p9 W
                reali = lenA;2 X: Z5 t, j* t6 h' T3 z
        reali /= 2;, _' r" b, o- o  G
8 ]! `; k; m; `
        int nconv = reali + lenB;3 P3 f7 `* c' A9 _( i' ^$ l2 v
        //#pragma omp parallel for, W3 s9 [% n$ B
        for (i = reali; i < nconv; i++)
/ n' f6 l% w- J        {
8 t& D% w% w  l8 J                temp.re = 0;: K9 G) F7 B- `! I$ ~2 {% _
                temp.im = 0;; A6 _8 B& Q1 ?1 W7 ]- p
                i1 = i;
- c& A2 S1 h: Y9 K0 W/ c! ~# `                for (j = j0; j >= 0; j--)+ w: X$ }: h% R' @7 Q# d# Z
                {* A$ l, O/ q4 `( {% g5 q. J
                        /* floating date operation */
/ u% U7 X. s* c' P( F& U                }
5 k5 M' |  _' ~; Q& P7 j/ V
        }! ~- r8 ~. c; O3 q6 z
}
& n" N/ i$ k1 l. B5 w2 W
) d' L! U, N3 w$ D' b0 m0 pxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样  E$ G9 K; ]8 N$ _* N; ~

, l, e+ V) i6 @% ]+ b" j/ A, Y4 t红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。2 S% B0 d; }- A  D
现在call xcorr 100次,耗时78s.* i/ O: i; f- r! p) w3 H
5 g  P3 q! Z2 _, i! C' {6 P
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. & n3 {& \+ v2 z, c, v

& a9 J' \; ]" ^* \0 y
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33: J. h9 |: l2 S2 E& t
Maybe Debug mode?

' z( w# C" B" w) v4 ~; D
) l6 I- g( L# H( ]5 b! i5 q; C不应该,看我上面的回复。" r% E8 x3 `& l

. F1 _! {1 j* n3 @我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
9 f: w( `$ T) b/ G+ v
雷达 发表于 2022-9-24 23:54
% z. k3 j* s; B( [4 y+ Y$ Dvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)" g; [- E3 Q' ^$ a$ Q; b& l  @5 J
{  r# A, ~  ^9 y: T6 g8 o1 l2 ?) `8 n
        comp temp, xtimesy;
' `# Z. w$ I3 S5 Y8 M0 C  n
9 W' ~4 @1 F. s/ |' p! X
这个不是这么比的吧。。。
) F6 X  C' X* p
1 t$ _) n9 ~/ Q; r' l您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
- u7 W, P7 b* k  Q1 H) f" v( Q. W+ Q. ?* V6 ]' @
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
. D* i% t) l; a( ^# k
数值分析 发表于 2022-9-25 00:20
: \7 N8 v; D3 }8 r; ?4 ]这个不是这么比的吧。。。
- t0 c+ c8 q* T: W+ L
( T9 e, x7 K& _4 r# R您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
: O! j! H, ^5 Q
" M' U# f4 {, L/ r9 R  z
有道理。- k; F' C+ w/ Q1 p' N- `
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
0 m1 T, r8 j3 Q9 W! R5 p- W
+ [4 R6 W" }2 q0 |0 r" m4 R我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46+ q( o' r9 k; p& s1 U; y$ U
有道理。
2 H9 x( P, J. y所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
  H! B' }$ A. l1 G! Z: M3 d/ b
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多: c8 ^& W* {" H1 w
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20, |( ]* G% }4 z" W% l' y
这个不是这么比的吧。。。) u1 g+ {' S7 S* ]' _
6 A, N: w% c9 W+ F1 X/ b
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
& H+ J( K( E9 G3 s- n; N3 V  z

% {; K8 g9 w. C* |! A$ g$ \% w9 y现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
4 ]6 G) S7 O7 B- |6 S3 y. n
沉宝 发表于 2022-9-25 01:48- P0 I' h3 r- C, }
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

3 c0 D2 _" X% y$ X5 \" f) ^
5 A# @7 f0 l2 {7 Z/ k/ L是的,兄台说的对。+ U: a- g8 B) l! I. S" W$ Y# W& u: g7 p

& E) [+ J/ h3 F& E4 \" {6 n其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。0 I* _) W; p$ w1 F! ^
6 Z- t2 k/ B" c) O0 D! F  ~, I" Y' B7 V
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。5 P( O6 O+ p) L: `7 p6 `0 E
! T! m* {) o( _) ?5 m, x6 n  d
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
2 P/ z! q% }$ [$ l- y/ M0 C0 E# V9 Z3 N2 ?! |" X( }
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
2 `7 e0 Z) O; C. D& J' J/ D8 i
沉宝 发表于 2022-9-25 01:27) q; y3 }) p+ g, f4 m' |
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
" ^3 r+ B" k4 [' g" x3 ~- d' [

6 N* E* H( E8 O又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
$ Y3 u4 k# L8 P( a" m. a( ^7 d: F& M. K7 U0 P
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
) S. d! j- s# E9 D* |. [又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
1 A$ ], y8 f8 O; I  ^
时间差一倍的结果可以接受。1 F0 w; W7 p) Z% g' v" i
" s3 X2 R/ J( O( D% I9 W
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
4 g$ H6 y7 p9 t* P4 n
雷达 发表于 2022-9-25 04:47
) A1 W  t% p3 }又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, g( o( f- M" j6 D8 \% D8 {# h& t+ b  Q5 V9 [3 i( s. v& {

# Q+ G; [/ u2 f4 x2 R* r; p4 s" R- ^- _+ `
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 0 b1 F: t1 L) d1 M. f$ @
数值分析 发表于 2022-9-25 14:58( q  T! X) }4 J4 e: ]! a
能不能把这个也贴上来,看看和上一个有什么不同?

0 S5 I: d5 O5 H8 {2 L' {$ y理了理思路,重新做了一个测试。
" C3 R, ^3 Y4 i8 ?1 G% {做了两个 vector 和 两个 float *, 都长 100000
& K% Z8 r1 \) R% j9 J4 X$ s外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.  o7 }. ]+ W$ F: t& |% B) j
  z2 W+ b+ C7 O" u2 v7 }# S% O
内循环试了4种方法,5 X6 M3 W9 }: ~
1. 直接调用 vector inner_product 247s * x, k& g( m7 r* u% {9 Q' `' g
2. vector 循环点乘累加 237s& J2 s5 e) _2 k4 ]
3. float * 循环点乘累加 204s; N. G1 |* s/ h* Q% \2 v
4. 空循环 100000 次 202s* P% x, c5 R% A& n& g& N  I
! E* b" ?% x5 i' ?
不做内循环 200s
/ y! U: W# I+ X0 u0 m/ z6 I9 }& J3 A) s9 ^
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
6 Q6 L3 ~7 m) Q. c另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
9 H- {. E( T5 |9 w( M4 {
" r. g; u2 [, k, e& n. O至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
* j7 Q" Q4 I+ m+ D, e4 W) Q" {& V
7 }: }+ U+ E! ^; K(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
: E+ S# v  ~0 c
4 P* m5 p; u9 _1 \
        std::vector < float > vec1(N);
8 b2 g' s! x7 Z, J        std::vector < float > vec2(N);0 i2 Y7 h0 E9 O% K1 O
        float* b1 = new float[N];  U& K& p8 D5 a! ?* x) ^3 W
        float* b2 = new float[N];
1 g" x6 B2 V7 C/ }6 N/ {5 l6 ^6 E; l) _( A- A3 ~
        for (int j = 0; j < 6000; j++); ?6 a* f) X7 ?6 j( d; s) w+ S
        {: V- g! E" \; a- c. B9 d
                std::generate(vec1.begin(), vec1.end(), []() {
: o) C7 ~& f4 q- Y! P                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
- [' B- n6 Y9 M                        });
+ i. X2 Q; {& d0 k6 I
1 O+ x3 B( P* Z                std::generate(vec2.begin(), vec2.end(), []() {) k+ S$ B. p% R
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;$ E' C. D0 c9 o
                        });
. i, |$ z2 ?6 t( K7 i, r; Z2 a1 j. Z* S
                for (size_t jj = 0; jj < vec1.size(); jj++)
" O7 q; b' _- W+ n7 J% u: x                {6 b! L5 [1 N: X0 ]/ ]7 W
                        b1[jj] = vec1[jj];
. p5 C; a& b9 U) U0 s. t                }& ~/ s* Y' ?6 `0 {7 ?9 e

% Q: C  q$ P: N5 A0 p6 o                for (size_t jj = 0; jj < vec2.size(); jj++)
" ^' y; O1 `7 U) W, ~% Q                {4 b+ }+ h, r: i6 d! h- A
                        b2[jj] = vec2[jj];
+ O  F0 K  {3 Q( U2 p6 s                }
$ M# ?6 g( n, k) K5 i$ ~* ~* x5 {7 [1 r8 d. b3 A
                //Method - 1  N=100000 247s  
; O( r4 L- ?2 P& A/ R1 K                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
  n2 m3 A$ r, J, R1 w                                " U  t  [7 n+ g7 \% I
                //Method - 2  N=100000  237s( D* O( x5 F% g+ R8 W7 {; r; `
                /*
; v3 z  _" |" S! D) v1 j& g                for (int jj = 0; jj < N ; jj++)& P# v3 F; w; \) F4 Q- e% B. b
                {: s3 A- q4 [6 r  R
                        fresult += vec1[jj] * vec2[jj];! v* M6 ]% W! _5 M  z+ b2 \
                }
, E% M9 M0 z9 Y9 h6 e4 M8 K                */
( E# ^* p$ Z1 S4 \1 m! ~3 i                                
1 [* O1 W7 h) \6 t# m                //Method - 3  N=100000 204s
/ @7 z% q' N* z2 }                /*1 c: Q) D" ~( {: d! ~$ j3 y
                for (int jj = 0; jj < N; jj++)7 O. X; o1 K8 e0 G$ R. h
                {
$ [+ ^1 c6 r  e' Z                        fresult += b1[jj] * b2[jj];2 v$ j& ^4 r5 x+ s) l5 R+ Q6 {
                }' i  C7 ^0 l( [, `- q
                */
/ \0 _" X, H. f+ k" f  q3 g; e% ]
9 D1 F; w4 C$ `                //Method - 4   202s
, |! J* e& ]! L: C+ @                /*+ M9 m: L3 }4 |* Z/ P
                for (int jj = 0; jj < N; jj++)& D$ [  O7 X- Z, D
                {
/ W4 r2 {! l: O; v$ _8 s% ^                        
. {/ ]9 I8 N3 G$ D                }
0 e! Y/ I9 v) I& V  d: d7 e                */
# S& S3 N1 n5 e6 s4 u                //comment out all methods, N=100000  202s                " g- ]. _" N6 r2 O  f
        }* t, K( W" f8 P: Y9 u' v
; |" Z3 f+ s) \1 j4 U9 r5 [
        delete []b1;  [# M6 F7 X+ j
        delete []b2;

# P+ ?# p0 E( Y6 U7 r3 U7 q
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
& M4 q" R+ ]* E1 n3 E$ E1 d: p% H7 x8 }
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?  O9 H9 b4 m3 W* o1 I2 h& B* Z

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:159 `& N7 b' b  b# |+ D, a, ?3 W9 y
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
1 X9 t( R1 i, G7 d* ~7 O& w0 I
7 A! ^7 f6 T. f! z4 j$ x你第二个试验里面的j在循环里面又重新定义 ...
) I$ p/ Z3 V3 ]0 I. W9 R
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ h( X+ @7 D7 I2 ]$ g

/ n5 c. ?! P" k- l( T, g不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
5 B/ j' z  d& ]& P1 {. r内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL* U# e4 V) ]& E8 ^
. N9 r9 D# X! n! \: V  ~1 `' s
不和它 ...

# \) S7 r8 `1 D7 Y9 A
( R( I( a- Q/ W9 b不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
# j- l% U4 v& q$ s7 i6 e后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54$ G% W( C: D5 V: ~
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)% b9 N! w8 v. T) \+ V
{1 T* b+ U9 C; I: N2 A" X
        comp temp, xtimesy;

9 ~6 [0 t/ N6 |4 s  Z这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。; z4 C( G# }1 d- k+ |( b
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
0 |: Z/ q. p1 A4 v8 @& IVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
9 d; k" \4 V- C- q, w$ V理了理思路,重新做了一个测试。* @0 z' {. B9 p: V  o) V4 f( y0 ~
做了两个 vector 和 两个 float *, 都长 100000* e( d/ e3 y7 V( x
外循环 6000,里面先做随 ...

$ m. p* b) P3 h" ]这个时间是从哪里开始算的?3 ?) U# {$ z. \7 e+ f; s- C8 W
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
- Z3 E/ e. u* A' \$ m+ T0 ]5 S按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39; I  K  S( H3 \6 m
这个时间是从哪里开始算的?% o% ]7 P. g  s% l# f$ l. k, q4 d
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
0 A8 \$ Z! j5 Z9 V2 i' L4 A
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。! A5 r& B, b" @4 q8 o3 P1 t" h
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 R" s8 a/ e! ^- r5 q" J
与此对应用数组(指针)花了2S% E! E1 B% y" A+ y1 Y9 K
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:540 S" Z3 o2 t* _; U1 X( _; \
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) \( y% v0 f' P/ T
{; E# f3 s- l! w4 a$ A0 M  L$ d/ f
        comp temp, xtimesy;
* y7 S. |! F7 z, o: L9 a  V3 p
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗* b+ t7 ^  Z; l8 [
5 I8 C. y8 A8 P* d/ [% ?

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
2 S/ r! c% V) [+ L1 ~我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗6 _3 u( s  _1 \6 E; q
: ~( j2 F) i  v6 ]0 Z: s  R
...
0 k& |+ F* y8 x5 q, ~$ U9 W
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
. S9 T1 N6 x) ~, G+ Y
& U  t: s: i; g5 q/ d雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
% Y4 N, X1 f9 d4 l. T
3 O% G1 O4 O5 `1 M1 m+ g是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。( G7 j3 Y! n0 I0 v6 m% C. V" ?
有空时我会试试 SIMD和并行,看看能提高多少。
! h" y7 B8 P  [+ w7 [% S" v2 q过去7、8 年没有正经用C++ 写过东西,没有 sense 了
# _, B% W1 q- I' C: s& m谢谢大家的讨论,I learded a lot.  红包已发  # m  M& H$ G: J; s4 s

8 p: `4 z$ g# b# A* E- ^5 E  T' G
1 S* [* c1 A1 r, {9 b  S! l1 U1 K+ |& h  X
- F# S7 ^# H  W- O) a0 j. I1 M3 Z' A: I





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