爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
0 A7 T- d/ @* u$ }* J
6 c; }: j" _( v. y! T. b自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
8 B0 a3 K$ R. Y% n3 y8 g% ~  ?# K
速度优化问题真的很有意思啊。3 t) ^! P, ~9 _: Y( n8 \& ~

! A7 S) o8 C0 k6 D. j* }欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?; u* Q5 ^% `* @- h+ d
把代码贴上来看看?
+ v  V6 B' \+ Z! J8 }7 D) Y. b* h8 J- P) h% h! U
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
; K3 w9 \; p! i% K8 B! E
数值分析 发表于 2022-9-24 23:04
9 u  J0 y7 G! s拉下来?拉多少?, g. ]7 Q5 w) E; a- F
把代码贴上来看看?
6 e% V2 b( [7 }+ f% }& @+ N; {

( b9 B% u, |2 }1 U$ Y: ?2 ^* mvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
* B# T; L5 ^/ H. }- y5 b2 L{0 V4 C2 {1 s; o9 ]. U# w
        comp temp, xtimesy;/ G' p$ K: d1 g) G" o6 m" ]9 u
        xtimesy.re = 0;: F8 G, v% I0 e* o8 L+ _
        xtimesy.im = 0;4 v+ S* Y! |4 A' Q
        int j0 = lenB - 1;
4 ~; S" L8 J  `( v5 H        int    i, j, i1, reali;
5 J* o( d3 m2 \        if (lenA % 2 == 1)
' q9 Y$ k' O) z: t, W) E                reali = lenA + 1;6 s' u8 [3 W, @% a" z* y3 J+ h
        else
9 V0 j; t, e6 I! o6 f/ F/ T+ v                reali = lenA;
0 V7 C, [( b% Q. b) V5 e* R        reali /= 2;, {6 _8 R' K  Z8 t2 Q

; a& u, u# p( M" g        int nconv = reali + lenB;
" N( |. `8 w6 p6 O4 Y" m7 X9 {        //#pragma omp parallel for
: K& @3 S5 f+ d9 H# L        for (i = reali; i < nconv; i++)5 }3 j; `2 {4 [# X
        {  @, f# E% T8 X; ]
                temp.re = 0;
! I& a. z- ]5 `- P, E/ {; g                temp.im = 0;
& D/ M& g  s) |# A                i1 = i;
+ k3 c  }2 \7 m: ?0 [0 n                for (j = j0; j >= 0; j--)' U# v, J+ j+ L( p. R4 x
                {* r6 i$ F" H& g6 }/ X) I
                        /* floating date operation */$ a7 t" X, H, X2 B% C
                }
0 D/ h" U; G! D% D  ~) p3 U) F
        }% O* ]5 M/ v/ K. @/ ^8 a* z& p
}
8 |. k! A/ A5 W+ }1 s+ N" U" Q+ `5 B. l: T$ X
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
6 v. X8 H. X. L) ?1 R" W# w% L( d! b8 M- f, w* \' `% A/ I6 T1 j
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
$ o- X+ e' k, N1 o( u* L现在call xcorr 100次,耗时78s.
* J$ `1 \3 j6 \: T! K
8 H8 T+ {& M( z( @如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. & N" V# ~3 |3 I; I
- x' \, v$ |- l3 Y

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33+ n' ~- y% W$ x7 T' |, e
Maybe Debug mode?
$ r0 i4 w+ x" N2 ^: ~% t# i
3 j: B9 o" k% S* N* {
不应该,看我上面的回复。9 B. m! L  l. W/ u4 ?  F9 P' d+ G& h

( a( T+ `4 n1 S, y) _2 F+ m我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 8 i# f8 }* _% K+ s) t
雷达 发表于 2022-9-24 23:546 W( m# ]& ]6 d$ x5 S
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)- B! N0 [! m  E% D2 b+ `
{
* @/ ~0 t3 ^/ q7 }9 N8 _        comp temp, xtimesy;
/ \) z- r' n1 f$ B! o" y$ a% [; c
9 N4 E/ q: E. }, m
这个不是这么比的吧。。。
" B% S0 T* r& K! i2 z' ]$ Z
/ Z0 E( ?) d& |, M: z& J& [您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。' g7 v: a/ i# z% j. M: o
. n5 a0 S$ P0 D  w3 T/ g9 f
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
% W3 l6 e. P) ^8 R) K, Z
数值分析 发表于 2022-9-25 00:20- D/ o7 D8 u8 L$ ]- |
这个不是这么比的吧。。。
, o. y# n2 f) q' K. A8 G3 U5 @* }7 j+ `$ K4 B' K! z' B
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
/ q& n. ~; }3 v# Y" Y
8 r: m7 m7 l  g& e7 H+ o" @
有道理。
0 C# r0 \: I0 X$ \0 u0 k所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
6 K+ X' _9 B& T9 B+ I# {5 t0 N: b* W- f/ {& k) V
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46. L! U/ B9 e* o" |
有道理。+ k- O0 c: `7 B3 D9 E  l2 X# E
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

* g, X; L3 p1 T- g你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多- i+ r1 T' R9 z) L
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
% F' w* K( r- M6 B这个不是这么比的吧。。。
3 k6 D6 U' A# u9 c0 [8 U, X) f" q2 K
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
$ Z: |" ^' Y! z; p; L# v

1 u6 F5 t7 g+ V2 U. b6 p现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
& M# W: ~! q% u4 n: Y7 G7 |
沉宝 发表于 2022-9-25 01:48
) u3 ~9 C" m/ N& V) q) N' V现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
. c+ x" H. q  i

7 K& F3 \/ ]& H' G8 ^是的,兄台说的对。, T0 m, \% i8 Z) o/ P# }, H

. P8 l/ D0 I# I) ]( k- F  v% J  U其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。2 O, y$ E: l: E/ M' c% d. n

8 Z( c3 A! R. B0 J! ]雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
3 {% k- \1 ~* }$ [& q1 X
4 j4 W* Y9 y- z9 S6 ^. G比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
/ ^( v& Z" v' Z. J+ V: o; N, E/ E8 x) E: j8 q! g8 G
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ( b1 H7 P4 E9 f( u
沉宝 发表于 2022-9-25 01:27! z2 X0 |- A+ {6 |& Y6 b( u
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

4 d9 P2 T' l; i& m, ~6 }
* z6 v. B; \6 h0 U* C. v* F9 I. W. X又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
& O! ~0 O3 k9 S3 y( m5 _
  _3 ^7 f3 U/ P5 }我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
9 H, W: ?! X( I& n- ]又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
, z2 Z) m. Y4 ?. S7 O2 d% \
时间差一倍的结果可以接受。5 K: M& j2 f& m* S( `0 C

( d# h( @' |. O: a4 y你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
. Y6 f. P! ]4 p& P) d7 W7 ?" d
雷达 发表于 2022-9-25 04:474 d( R' g/ e6 K- o# X3 p
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

3 c; m) T( i9 C; ?4 x  q: C* R" d- R/ b( K0 x$ i8 {7 p  ?
" q/ J4 I8 J2 X/ H' w1 U* _

3 }, D5 E* v" j! F4 i/ P' w能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
. M9 u7 u! x- S; j6 O% g1 \
数值分析 发表于 2022-9-25 14:58- C" b4 i4 m4 f. s' Y' N
能不能把这个也贴上来,看看和上一个有什么不同?

# I- T0 @  [: D/ K理了理思路,重新做了一个测试。8 K. r$ a, H: J6 o; z* w
做了两个 vector 和 两个 float *, 都长 100000& ]" O9 S# ?1 n! u8 _( e  R  p( [
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.4 G* I3 O! G3 v0 U/ C& Z

1 {7 I1 X0 |6 Y9 f9 P6 Y. f内循环试了4种方法,% f7 F3 k5 l- R9 k4 _9 q
1. 直接调用 vector inner_product 247s
+ ?( x6 Y; A. F) m2 H/ h2. vector 循环点乘累加 237s4 T6 w. P# _: N! q, S# Q/ ?5 n" r
3. float * 循环点乘累加 204s
. E1 |9 p& z" t$ |& o; H$ ?) ^& ~4. 空循环 100000 次 202s
* f  g( V, K" Q6 M/ Q3 C% w& W7 n1 i2 C0 |. L' T! S8 G4 `
不做内循环 200s0 ~+ n; z  C1 v$ ~) Y  o
- Z) L! ^& F' ?" D9 J; m
你昨天说的对,内循环本身占比是很小的,大头在其他处理。) k; i5 |3 g# x# Y0 W$ k
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
' j4 @. A7 ]& d' M# U) r8 y
# y! ]2 P4 I5 N; ~9 o至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
" J5 q  w" a( q( m( v, {+ [" x. a- j' P& P# Q6 T( m
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)4 i, N; o6 _, b/ Z
4 `" [6 h! {) e8 p' h
        std::vector < float > vec1(N);
9 f$ n0 E% c( `. r7 _; F* V        std::vector < float > vec2(N);- i0 @+ S" N8 u- l1 Z& \8 d
        float* b1 = new float[N];
$ T" L/ m0 `- O, }        float* b2 = new float[N];
' `6 a8 k9 P. A7 u! F$ i8 u4 o0 B8 a4 h* ?2 [
        for (int j = 0; j < 6000; j++)$ W" R; |1 m- R8 ^4 M. e
        {
+ z9 U/ P' N7 c0 R7 z  J4 m                std::generate(vec1.begin(), vec1.end(), []() {. O1 U. G2 H6 ]
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;: ?* c4 ~% Y* i  ^8 u
                        });  V; \/ j5 m) |! M+ w

2 p' v# P0 k% _1 b                std::generate(vec2.begin(), vec2.end(), []() {
! f" E1 I% X) K/ D3 g/ i+ _5 F                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
5 S3 |. _4 O! }/ q$ q/ n                        });
. y8 k. q& \0 B# |; L
! f3 E8 p5 o; @1 J# a                for (size_t jj = 0; jj < vec1.size(); jj++)
0 _4 m: I( `+ g* \) R                {
+ I: P4 o5 d6 N% d- d                        b1[jj] = vec1[jj];
2 r4 c! q2 O, f7 m# a1 g                }
2 y  y& J" ]. k8 E- T4 P% j3 @2 U4 o! y8 R0 Q# q' F
                for (size_t jj = 0; jj < vec2.size(); jj++)
2 u% P9 _9 {* M0 o                {
9 C) ]- Y- K# h* Z& P( `                        b2[jj] = vec2[jj];
6 `" u! W4 S1 s0 c; ?9 G1 t& L                }
3 X: H( G1 o0 u( P7 q5 ?
" h/ s$ T- O! G& D                //Method - 1  N=100000 247s  
+ F$ c& x' S( }7 T- c9 q                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);: G% E9 j  Z/ B5 ], O: N. j9 l$ Q, I3 M
                                
+ f) X. [, d/ Y, i! E, M                //Method - 2  N=100000  237s# {" X5 m7 p; F/ g
                /*# G+ b5 H5 Z4 z' T
                for (int jj = 0; jj < N ; jj++)) q$ @5 [% \. [* V
                {
& P: k7 ?2 Q: Y2 D( p: u6 m                        fresult += vec1[jj] * vec2[jj];
$ _' N- m0 h5 R2 |& S                }
, T' ?$ m2 ~' l9 j0 C5 R                */$ ~. P1 `6 P- k0 K
                                . k) ?4 S; a* C3 E0 X
                //Method - 3  N=100000 204s
  K3 ]* E: F0 W0 }0 K4 `6 Z+ E                /*
6 Y) j+ t. M* X- ?+ W1 M5 l                for (int jj = 0; jj < N; jj++)
5 |: V) u% A( u- b                {
  X/ ?7 M# }2 s* ^1 N                        fresult += b1[jj] * b2[jj];
, C' u" ]' l* ~+ ?* w+ S$ ]( P                }
5 O5 R  O# N+ a                */
7 c5 e# z4 W' [/ @7 \
8 k3 b1 n( v+ |6 k3 r' S                //Method - 4   202s
7 B; u0 K1 i3 C; M# h0 d2 o                /*8 H" ^$ _( d2 L6 {& M1 r) n2 n
                for (int jj = 0; jj < N; jj++)
( L. B9 J6 }9 N% q                {0 u( |! O  h0 B
                        
& x% |) n4 ~$ w& H, C                }2 r4 `5 o$ s* Q3 R4 L2 M
                */
9 S6 U5 M/ J( T4 G+ ?; L/ V                //comment out all methods, N=100000  202s               
0 p  _% [2 o0 g9 Z- h' a        }
+ D9 N) U# v9 `* x- W( c/ L
8 m! N8 @! X! r4 X, S& G5 G) A        delete []b1;
! l' |! @/ }3 H. q1 ^        delete []b2;
2 D6 c. t( r6 y

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?0 d# m! {' ]% F0 I
) w3 w- \* `6 E9 o; B3 b  ~
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
. l, X% R2 N+ ?! X1 F& U0 u+ @2 J
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15. _0 m) Z' z+ Z! ?5 h
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
- Z% a) R- p& j5 T. n  t$ k& b4 ^3 y' A
你第二个试验里面的j在循环里面又重新定义 ...
" n: v. j9 ?) T5 Q
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL( m2 h9 _  c6 z) u- ~, e

0 h+ `* ]: R( k3 @不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
' |: z6 a/ g9 J# \+ l- X3 L内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL  N0 G" u9 q! ?$ \
* ?- ]# ]" N8 l0 E6 A& m2 W* j
不和它 ...
* i. o/ z  f6 g4 u

' K: C, Q4 }/ }  q, Q; G- c不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
( p* ]- O2 A: I/ s: g/ P9 x  M后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:540 o( z4 C* y& R* T/ |3 c# r
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  \" G3 G& b9 p' r7 k$ |; C. I{
: W0 R+ s8 ^# g" V6 F        comp temp, xtimesy;

/ C8 M( v! Z! E' g+ R( h这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。) p1 |  t( ^  g& M' T- ^" p$ m; z8 s
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?( v( d  \. f3 T
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30. U$ _( W" U9 U
理了理思路,重新做了一个测试。4 Z9 Q  B" K9 `- P* T3 \2 \# U
做了两个 vector 和 两个 float *, 都长 100000& j  B0 \- ]0 f2 P7 C$ B. ]6 E
外循环 6000,里面先做随 ...

6 C9 Y5 p4 r3 K" s5 X( L- g这个时间是从哪里开始算的?7 a3 @# |( V& z, @' h( m# [
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
* |: q2 q$ K- m按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39+ Z0 V" `4 n( Y! E6 _: I
这个时间是从哪里开始算的?5 F' S; g1 [5 _" H$ z1 g" o/ `- I6 ]
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

2 l! g8 I* k) R5 s( u+ |/ C我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
1 I( i" w9 V3 r, {你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。) y/ G  e1 [3 j
与此对应用数组(指针)花了2S" O8 ^! X1 v+ G" W, q
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
% b# l6 m( m# Q9 [( zvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)/ ?* w" r' e* |+ l$ k" B
{4 u1 j) m9 F2 g
        comp temp, xtimesy;
9 ^- _3 I' o4 |! j# k
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗) {6 X+ p# E0 M; r2 O! O9 }5 `% R
4 p: C9 `$ I4 S& @

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29% x5 @7 }7 B- ]5 M: l6 w) o) E
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗0 I+ p) K9 X0 C5 i

0 N* h6 V9 ^- ]+ L& b( [ ...
: N+ n" W& d2 g2 ~% M' k
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。  W% J  D+ \0 o! x* \. @
: S& {+ `6 K  ^* B, d0 b
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
! v/ [8 ~* W& J. C2 x( X/ ?) f! M6 E" m: u4 R5 T& O
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
3 T7 Y$ `% Q- v$ K" o有空时我会试试 SIMD和并行,看看能提高多少。. v& M- G" `9 K8 x
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 9 s) ^6 O! ^0 ^! c) _
谢谢大家的讨论,I learded a lot.  红包已发  
$ I2 {9 T% J2 |1 u* K% e2 E' k. Y7 n/ i) L8 f( T! Z

8 Z# f/ ^; e, I( ~, u; E. E, q) w1 r# W; R, s

! e2 f$ M" {: f4 R




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