爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?+ A5 g& Z& \% x/ I

- h5 A2 k8 ~: i5 N自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
2 x  W: z6 t7 L; P  ^8 N" ~/ _- C1 v
# N7 ]% R. {2 y速度优化问题真的很有意思啊。
, S; k* G* p  a* h. k* I: X' H# m. h* u& M
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
, p2 n4 W/ t) K- |. ^把代码贴上来看看?; a  p  {" }* C

! G& F: j# Z9 W) c7 ~& S: G难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ' b5 A" K: A( C2 [
数值分析 发表于 2022-9-24 23:04
: ]  L3 Q( d+ u' l拉下来?拉多少?
; L  |: g  Z4 F把代码贴上来看看?
* Y' C) D6 q8 x# B0 c: y& W
; l) G( B- l! W5 y! G/ X3 B
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)1 C+ ]4 X0 F& K
{
) F. c2 s; h. p- Y% I1 d& y" \        comp temp, xtimesy;
% _" ]0 s1 r1 E6 [        xtimesy.re = 0;
3 S" }4 u& a) @2 i- k% f8 N- c        xtimesy.im = 0;
& f; o1 A$ k( {4 _        int j0 = lenB - 1;: X1 |4 m$ a& z4 O+ A- R: Z- a6 {- S
        int    i, j, i1, reali;- O7 A3 [* ^0 K  x. k
        if (lenA % 2 == 1)
( M# J# o' P' n' Z; S: p) c4 H                reali = lenA + 1;
& _+ m. L0 V) k" h  E: n; G9 x% f$ z( m        else6 B0 r2 q* ?- c  h' U: F
                reali = lenA;- @: w4 ?: N* ~3 \( u' q3 A
        reali /= 2;% J* y4 H7 h- b& W" R
* ~4 B- c. @; u, o- R
        int nconv = reali + lenB;: n/ f2 p- ~% i7 ]
        //#pragma omp parallel for
  k$ ~. b6 t( \( S5 T        for (i = reali; i < nconv; i++)# }) M5 p. \/ t
        {9 `, U, [2 g* J, ?
                temp.re = 0;
7 h$ q8 q) q# \; @$ I8 W) `% k# u8 a                temp.im = 0;
1 ^' o9 c' a6 z7 _0 M                i1 = i;
" D% t) h! K2 H1 l: Y7 {+ j                for (j = j0; j >= 0; j--)2 W0 T& r! M* P4 i, N( ]
                {8 j: I& L; _; S" t
                        /* floating date operation */6 }3 r  l$ A" W8 D5 ^2 [, A
                }
* U" \+ n# a1 q7 H9 c: B+ y* ]
        }
1 P3 H: q( t6 r! h& K}- t6 m+ Q2 r+ L3 v1 B$ T$ ^$ ]
9 M2 t4 |7 g9 d& S! L: |# H* r
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样. k2 y' y( ^: w# n: W7 b! ?6 _/ U

. p( V$ @- G% M9 \, r4 u红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。1 C' B- [# D% I( i& l" b
现在call xcorr 100次,耗时78s.
$ y2 R( W7 V2 L( |! F7 N
( v- _" c4 A5 n, N如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
+ G) E5 o/ P( N. `; c' v$ C8 w  r0 o2 v. p0 M$ g7 y

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
1 I& K+ f  ~( G. V8 _* YMaybe Debug mode?

9 p- O( t9 v. ?  A7 ?: r) F7 B* ?8 C" i
不应该,看我上面的回复。
9 c& l. v- I% Y: Q5 O" B" v$ ~  e
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
  \5 H- ^7 \; P5 ?! d* l0 N
雷达 发表于 2022-9-24 23:54
+ Y. z5 ~1 f( t6 p1 N4 nvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
3 }% x, ?, k. ]1 @! T1 {{
# p: x; K' u1 n4 y' X; b6 D5 Q        comp temp, xtimesy;
. S3 t0 T* |, a' S4 W

1 w+ `8 p5 M( @7 C这个不是这么比的吧。。。
: g9 c! j( z' J8 m, A- x3 c4 u2 D0 _# h4 @6 x0 W$ H
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
2 _0 I. ~/ e: t! k' K) ^
( C% P, c: U* L; s而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 0 r; u8 h+ X7 @# b$ I
数值分析 发表于 2022-9-25 00:20% ^- O: A" R: w& ]. L" \
这个不是这么比的吧。。。/ c6 z% N+ q$ i9 `" z% p
' ]' ?' Q6 X: u
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

1 {$ w) [- x9 G/ Q( i; a* Y+ J0 E; q( z( h: m2 i
有道理。6 }) }, j; d; E" ~3 F7 Z
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
& _3 O  l3 j8 F" C+ O6 C3 g9 W) j3 Q7 f5 c1 o1 v0 l! `
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
3 s7 ~( V( z8 Q8 A7 Q1 g, [有道理。
( B! A+ V# l. W所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

% ~1 H  Z* \! y7 ~  r) ?* I你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
3 j' R* ?& Y0 n! \4 r7 e: |! tWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
! S- N5 ]" P, J" C; W9 c. p* X这个不是这么比的吧。。。7 q# k: |6 N8 B' s

. i% x# O" H" T) J: a9 W您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
7 c, j% R7 o. B* j; k- u
4 {: @5 b, Z) f! P! Y2 L% J
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 # u* s% l; j6 j0 @6 R
沉宝 发表于 2022-9-25 01:48
" C. h; r2 `0 }; S' n9 o现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
: o8 X" J8 F0 s0 n, H6 s: Z7 i

, u3 H+ F' y! d7 _' u/ O2 k5 V: _是的,兄台说的对。* ~$ N0 A3 [! e- [- L* d" H( B0 j) k

) M5 R1 t9 n, m# E& M其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
4 B9 M5 o4 I) u1 \% u5 L+ {/ e1 n# f1 M. u6 o- ?
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
1 {! y- ?% n9 e, j  ~" e& O' e$ Z
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。& P& \% f) n7 D. U6 K/ C
& O: ^5 F+ |( S/ o  v
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 3 [( `* W3 ]+ ~$ \
沉宝 发表于 2022-9-25 01:27
; T6 s% f6 k: C( ]6 G你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

0 V% I( [0 s  U; r, \6 M' ]$ s# ^2 i5 l  P6 y4 P/ i
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
- K, r- P& s; P
* Z4 N/ L( C$ E) Y! A4 G我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47, i# `' O- T$ `' E
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
, D" A0 T9 m  t8 L4 a
时间差一倍的结果可以接受。
1 |* C9 |% t. k1 M1 D0 P
5 q2 u! S3 |- m3 [7 L你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 & d9 w9 B" t/ U: R3 E3 M
雷达 发表于 2022-9-25 04:471 J/ t6 H& p- |! ^
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
4 x& N  T% S. E: j& Y: K& W* C& E

& r; D+ O- v4 ^# _0 T% T
; [$ M9 N$ @8 ~3 E2 z6 q, i3 `
3 E; R2 U% g2 M+ l/ J能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 : {4 q7 c) C# G
数值分析 发表于 2022-9-25 14:58) q2 {( U: ~% F% j
能不能把这个也贴上来,看看和上一个有什么不同?
) Z- Z9 V1 G" Q& d
理了理思路,重新做了一个测试。8 ^2 M) I4 t/ y
做了两个 vector 和 两个 float *, 都长 100000
8 R2 l/ r" @2 J4 L8 Q* H外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
( X! r+ v3 K, Z8 _6 Q: U6 |- K( U- C5 s1 w; I& f
内循环试了4种方法,
1 U/ `# A" T( T1. 直接调用 vector inner_product 247s 2 @, g# U; ~* e, m' z* ]2 R6 I
2. vector 循环点乘累加 237s; f0 W* J6 A+ t1 v5 b& Y5 e2 B
3. float * 循环点乘累加 204s
8 e. @: i- F  d, l3 E. b8 O4. 空循环 100000 次 202s
7 j9 u. D1 t. u7 q6 o' e7 T$ M1 x& J* o8 U- F4 y
不做内循环 200s
; g3 ~3 ]0 D+ P- Y$ R. y
9 d9 v1 O( N. l8 N( s5 f你昨天说的对,内循环本身占比是很小的,大头在其他处理。& M) E0 f! a/ d0 U
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。& j4 G3 C  q. Z) k5 g
* q$ U8 t+ w/ n: ?" F( Q8 R/ d
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
* i7 ~- g; A5 [: _" {/ K4 W! ~4 C) p; G7 Z. y
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
# ~9 k% R; f, ]% `' T- z0 y, g+ f9 T, f; E* H3 Z% w+ x
        std::vector < float > vec1(N);- l& ^! P2 m( |0 `, A, t9 v
        std::vector < float > vec2(N);$ m5 D0 @7 ~# v4 W
        float* b1 = new float[N];
9 |! l3 `/ {' [6 B8 g9 D4 _        float* b2 = new float[N];
: `8 }# C7 @5 l6 B& l
" u. b# v' ]) [$ a) n" Z" c        for (int j = 0; j < 6000; j++)* q+ |2 H2 E% S8 a3 s
        {: |2 S: Y- q: f3 }# Q- u' w8 S
                std::generate(vec1.begin(), vec1.end(), []() {
0 e6 X: a( h. ~, Q% K  G                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;' i7 s  W' L9 ?' k
                        });; D0 t7 |! q5 `- n
% {, l* ?) C7 B  ^) q
                std::generate(vec2.begin(), vec2.end(), []() {5 X8 }/ d+ t0 z/ O
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;7 e" y) g4 H0 @  @# I
                        });- M9 q8 u- u* Q3 o( `0 t  X; G* k& `; e
* B2 V4 \0 P. r% P. `( [
                for (size_t jj = 0; jj < vec1.size(); jj++)6 N0 I. [1 {2 f9 O2 N: R4 l' A1 r
                {
! X; k, w* Y3 J4 y1 w" ?                        b1[jj] = vec1[jj];
) D7 T/ y+ c) H6 I4 \                }
, c! z8 I, W' n% X: _7 \7 z; q
0 v2 ^7 c* m, _: G7 @+ a                for (size_t jj = 0; jj < vec2.size(); jj++)
/ _+ _  W- F9 f# A) P  S                {: V2 i) j; Z( v/ p3 C0 l& h% C# w' ~5 P
                        b2[jj] = vec2[jj];
: K. p( |+ a% V                }6 Q  V4 O* }3 a3 e0 d( J% T4 I( U3 O
) T. E# D* R: |6 r7 {& r. C3 W
                //Method - 1  N=100000 247s  
  C% l7 {5 k9 u5 z$ [                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
( H% b- \! n; W                                
- f' n% s) a) w& D% k0 D; z1 @$ {                //Method - 2  N=100000  237s
; e& e5 p' g8 `$ @/ U* s                /*
  c0 B' a! h) W6 S3 E7 K( F+ `4 x: U                for (int jj = 0; jj < N ; jj++)
( F: [, u4 p) u  {8 O; p: w                {
/ o" G! ~; e6 _4 O  j# n9 X                        fresult += vec1[jj] * vec2[jj];: g2 b0 p4 L1 A& ^3 t
                }: y4 |. p  `) w( A$ s
                */, {$ n: b9 ~) Z: S% G: w
                                
* Y5 t% j6 W5 L  |0 p                //Method - 3  N=100000 204s: @. v& z. X2 f1 P2 R% _! X
                /*
1 \' \; q+ x! g" O+ W& X3 }                for (int jj = 0; jj < N; jj++)/ J9 h9 U$ e* C) K  V! c7 W3 X4 b
                {' v- j- `& F' N& o0 n3 w: Y
                        fresult += b1[jj] * b2[jj];
# q, w& \# q8 p! |                }( F2 w: w6 `6 [1 T& ~7 O
                */- Q6 ?; v9 G7 x
2 q- {3 R  L4 {3 v' B8 K" Z! |
                //Method - 4   202s
5 }  F/ U. L1 u. C0 K+ p0 T                /*7 A/ G& i4 U! \7 A( q
                for (int jj = 0; jj < N; jj++)
3 y! W9 t2 Q* L6 ~1 A) E                {* H/ z( a& o/ c" P* h: M+ E9 s
                        2 ~! e4 ]' J) `/ a
                }& f: a9 E9 a' D  v+ [& ^+ p& b
                */5 J: ~$ o# {$ p/ E3 G
                //comment out all methods, N=100000  202s               
) ?" Z; H  G6 [% |* i* m% `4 w        }* w& J$ L( j: `5 @9 g

6 k2 P+ G' V3 V  T" u: o        delete []b1;
3 G+ t- M% d; o7 H& v        delete []b2;
5 \  O# [  @8 @. x7 W

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
/ ^7 g$ e9 J; y$ h; R3 F
8 K# V5 Z, e- j0 B/ S* U1 H你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?( Z9 U8 I8 j  {2 `! u. @! a

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
- l6 y3 P7 ?9 [6 i瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?2 Z/ {' x2 ]4 n# m4 j. U
8 D3 u" Q5 _& u1 v' i; W
你第二个试验里面的j在循环里面又重新定义 ...

7 [) {2 O1 |- C; _内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
4 z" ~0 y$ m, L. J7 k( A; |$ ?( B& E
, w; b" W) e, m/ |6 |$ c不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
, k, p, E' Q: u: L$ K内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL* c% w! M9 v, l( b

+ M! ^- j2 |0 W  n' k不和它 ...
1 m8 K6 t0 W4 [1 V. x% S/ w/ H
! l/ z' A0 c0 B0 N2 @6 e* M# {
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
4 y' K/ w3 \; j2 ?. [后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
0 b4 I. c! p! D' H9 P( z4 u) Avoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)* G3 }- A. `0 i9 E
{9 V3 R% f; `% e/ q
        comp temp, xtimesy;

, ?! c* G+ |; R1 u# C/ P这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
1 ?0 M! z) r1 \$ [内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
6 Q6 c' Q! ]; dVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:302 X. Y! I: Q$ j  H4 T
理了理思路,重新做了一个测试。" T& K1 |1 u+ T  C
做了两个 vector 和 两个 float *, 都长 1000002 d  E6 J8 M0 v
外循环 6000,里面先做随 ...

. c* n; H) c! i, `: u这个时间是从哪里开始算的?
& G9 B% [& o0 n& R2 l/ n/ Y4 U我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。, `2 y+ {' O9 @2 B$ v+ Q
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39; {: b+ T+ M- C# L$ i
这个时间是从哪里开始算的?; e  ]( p" @( w% h
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
4 h& h* Q. n0 B7 ^! ?* A% Z
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
; P$ n& }7 r3 G# M你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
5 [2 B0 W, W+ u* [6 _) ~与此对应用数组(指针)花了2S
, N4 e5 C- D6 K你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:542 o3 Q4 p- q* M7 m9 e2 g
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
' u5 A" `4 t- g- J, l{: G& ^; p9 `$ S: c1 C9 N4 @+ R( f1 E
        comp temp, xtimesy;

( ?# Y* |; m1 j/ U  g我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗. `* s8 f$ E( H* P

" W: t$ ]9 F& M( L4 r
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29% X7 D+ k+ p+ ?! k# Q# G7 b
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
& r1 u0 v- d% I$ f: [' ]2 ?1 U- R1 \8 {8 Y
...
) x2 n5 Y3 M9 Y8 a
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。( r' e: ?# I5 H( s4 K% O; n- q: J' X: f
  k  [' a7 ~& J9 f" T1 k
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 0 A) j7 K$ D6 q: n* U$ `/ d" K

7 E2 _# _+ b4 M1 \' \是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
6 v7 J8 a5 m; V有空时我会试试 SIMD和并行,看看能提高多少。
& C! D; ~( R$ q8 H: m) Q过去7、8 年没有正经用C++ 写过东西,没有 sense 了   `3 q: Q% X9 X( F" D. J+ X
谢谢大家的讨论,I learded a lot.  红包已发  6 _/ l; q, i) @0 y0 J3 u

: Z- @* G4 P0 h8 s5 Z: j8 u* B: A6 C1 y
& s) x  k% n* v! M- G4 X8 k5 J7 M/ U& |$ {( ?

: j3 H+ \# A  ]! g& }' o# i, P" y




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