爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
2 Y2 x3 z) m% {& g0 }( x2 t& e
, b( I1 W5 Q) g/ G8 d自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
/ ~+ ~  [0 q+ S3 t9 ~1 |
: ]# ]5 P3 j4 d$ J9 f速度优化问题真的很有意思啊。4 U; Q% h/ t1 U5 q& \4 j
: U' a0 x( u. o! P$ z6 K6 Y' K8 t# n
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
3 g, r* A  ?) e; b. Y: I. f/ b. L! P把代码贴上来看看?
: a7 a4 e  [: ^$ m+ j  P- p8 y! @/ I/ P% k  A6 r  o- S; O
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
- h3 @' c6 \8 X9 `
数值分析 发表于 2022-9-24 23:043 L9 K( u+ X% n% V5 \- I# M/ R$ b
拉下来?拉多少?$ P+ ~& j8 W+ ]- j
把代码贴上来看看?

+ ~' i, r3 T8 Q6 V; U% E1 K9 d9 R8 r; _0 D, c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  ]% a0 d% w7 p& y3 N' i$ s{
5 l5 h6 L6 I1 n; |, J        comp temp, xtimesy;' j* M. r( D- e. Q8 r/ l
        xtimesy.re = 0;
2 T: P$ \1 j9 l- Y! J& L        xtimesy.im = 0;
& g; }' l' @! E( ^        int j0 = lenB - 1;6 g+ O+ I% k* E# W8 F1 Q
        int    i, j, i1, reali;. i6 U; E  d9 e3 X! W# r" P: j
        if (lenA % 2 == 1)' N3 ^# K7 ?" P* M) s# ~8 J1 a. Z* J
                reali = lenA + 1;
, U- D, f& ~: D5 `) E$ Z        else/ c% ~) ^3 f. Q* }. z. T' Z+ H
                reali = lenA;9 o7 l4 l& M. f3 b) d0 ^1 W
        reali /= 2;
$ W( Z" [, g  i6 E1 k- G1 K7 j7 @
6 O: W/ a# ~3 F5 w        int nconv = reali + lenB;& J; w7 n  H0 `0 W4 u% S- k
        //#pragma omp parallel for
. E  c2 m; G0 K1 `. [        for (i = reali; i < nconv; i++): ^; J/ d" A5 N
        {
: x' I" y, {2 F0 B* ^# U& d                temp.re = 0;" ]( s! l7 X0 N
                temp.im = 0;
' |) D  X0 F4 q: I5 V6 X- O                i1 = i;* {. b2 M2 q7 x, y4 r) d! M, d
                for (j = j0; j >= 0; j--)
, e+ T5 G+ v2 E7 _0 U4 [& Q                {5 _$ J% `2 B6 i! f
                        /* floating date operation */1 A' @5 x: x' V8 }0 s" h. j
                }
8 g$ W( M4 X# a& Z: e9 |
        }
* D+ g& k  U9 W: W}9 P$ l5 g+ J& R) `
' P5 U- K; r/ g
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
& H$ O8 ?7 Y* k3 o$ ?% L  \) x
9 T5 N; |- Z: a& c( X红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。  w; M3 B0 z+ ?) \6 }& u( j% u
现在call xcorr 100次,耗时78s.
' Y) T& ~+ w' a3 r7 s( T" s/ N' \$ @+ C7 d' S9 J3 i
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
: M" U. c8 V6 x* a# H$ Y. h$ W8 ^" M/ F" e% [" v; ^, U( g. h

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
+ ?$ r( M6 D6 U) S' J( P+ ~- hMaybe Debug mode?
/ U& w  A1 S7 a5 k2 p# |. p* ^' |" f( D
3 g! F( W2 \3 l* r
不应该,看我上面的回复。: k" [) q; U( P) D9 c
, A3 \4 e  `9 ~8 g: l
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
3 }( g6 H! \, \3 K# E9 _& b
雷达 发表于 2022-9-24 23:541 c, F; {$ T- `3 C
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
8 U& ?5 R* t" z7 J3 c; M{
8 d+ ~/ U& U: J$ b        comp temp, xtimesy;

+ Y8 x) W% |0 U9 k6 x, E# d8 L, u: L0 A* k
这个不是这么比的吧。。。+ d5 M" s; W6 [. y8 h
- A/ O' ?  x8 l( j" E( Y# c& g
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。; p" T7 O$ S; {# F
' F7 Z, d2 z( u) I* `
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 $ o/ o1 `3 b& I2 M8 [/ x% r
数值分析 发表于 2022-9-25 00:20
; n7 a; R2 u- `; f9 o# {这个不是这么比的吧。。。
& U: c# ?9 ?6 G, s/ D. t
9 X2 T" x9 B/ o! D您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

3 I( W1 M6 {. Q7 m+ L9 o& ?+ K% H' q4 e' V
有道理。
; u- K" D% W% `# Y所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。, r  T3 x) f3 s, k8 N
1 w4 t- `6 i9 g
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
: L. _" Z1 `: W/ L" y有道理。
! G( i- F5 F3 k% h; q' v所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
2 D& ^" i! c: B2 L6 O
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
3 [1 @$ w. ^1 p, ~Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:208 a: Y1 W( R: |
这个不是这么比的吧。。。9 C  y. |/ h$ D0 G9 ~# A
  j! G3 X- k: ^1 u$ C: u+ V
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
( s; d  w, m, S

4 b: q" p; M6 P现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 2 [4 p& a/ h6 [' n) H/ r
沉宝 发表于 2022-9-25 01:48
- |" I, [4 r3 g0 H: ]8 }现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
$ f  x4 G/ E* e3 }! k  y

$ O% w7 n; M0 w9 z; b是的,兄台说的对。3 t5 U3 y4 F9 i4 B

0 k- t' b6 P# |, n# K其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
$ w: R4 h7 k; l" @/ \5 ?
. v! z4 f1 c2 }8 O6 d) Y/ ?雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。5 B6 q! r6 A1 j2 `8 u# ]- |* I

8 ^, Q% i9 Z/ G3 O% ~比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。) ?) }# X% `7 r, I4 v

7 Q+ i0 `2 d/ q当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
$ N' `$ D# a# Q( A
沉宝 发表于 2022-9-25 01:27
, d( |$ O/ d) W, v" A你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
' o0 j; r( ]$ \4 ^
3 k+ ?' R* b) C
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
5 u5 T. n! k; v  {; K
8 }! c2 ?, O6 v+ n: w4 M: K% V我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
/ A5 t- n4 N* w又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
6 T0 j  \7 e: j4 j! @
时间差一倍的结果可以接受。1 K8 o" p0 _2 p/ `9 n' e

2 r3 O' J" B% c* D你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
+ \8 V' m* F4 J+ r' y! O$ B0 Z
雷达 发表于 2022-9-25 04:47
/ Y- i+ C7 u7 I+ d又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
5 n6 q: Z  g" M, w& F6 U, \- W

, i& d8 b, d2 \- I+ w8 g; ^3 y. ?4 q. n2 t3 h
0 `- q, D9 |% {; O0 K4 x
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 4 i! A: T7 o7 t6 Y' R- P
数值分析 发表于 2022-9-25 14:58( ?( X/ B, ?- f0 [
能不能把这个也贴上来,看看和上一个有什么不同?
0 r) x* H% e" e1 d
理了理思路,重新做了一个测试。1 y+ q, z! I/ o* N# c+ {+ Q6 K# a
做了两个 vector 和 两个 float *, 都长 100000' ~9 y9 T* _# I( h, H
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.# O! z2 \, y# m9 R9 ?' X

7 P9 |$ V! q2 K& B) i内循环试了4种方法,
. Y8 c! A- }' g+ ~# b0 P8 Q1. 直接调用 vector inner_product 247s " G4 x9 d3 D. c8 E
2. vector 循环点乘累加 237s" _0 V/ z/ M$ ~. ]
3. float * 循环点乘累加 204s
: Q" i2 Z/ g9 ?  p8 ]4. 空循环 100000 次 202s: u3 y1 i( d/ O$ i

" g: m# K' `# t' }" ?4 A! q" X6 p' c不做内循环 200s
- u7 \- S+ s6 W0 P9 ^0 f- K3 B# V( G$ J+ \4 O) L4 u
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
0 [/ K0 c8 b" J6 [另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
4 \7 ~! F% u9 ]) a0 I  T/ k/ n; E' C0 U8 b+ G
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
4 |! f* E3 p8 @# C! c+ o" j. X: ~6 Q' M' x& a/ q
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
; A9 C8 `9 c1 ^6 g9 Y5 c/ [5 w' Z0 y& D% y9 p+ J. @  E
        std::vector < float > vec1(N);
3 j4 T4 X4 d* Q, W; O6 H, x        std::vector < float > vec2(N);, I7 M  F* k: ?9 _4 S3 h) P! ~
        float* b1 = new float[N];
( [/ O9 k, Y4 [; W* O        float* b2 = new float[N];0 R+ m& d' K' M4 Z( q

0 \# E( [* o) l4 |+ ]5 B0 u        for (int j = 0; j < 6000; j++)
' ~5 o- c9 a, I/ G/ ~        {
' T. V& R) V, f! m5 J5 d0 V* g) N/ p. W( b                std::generate(vec1.begin(), vec1.end(), []() {' p, c# A# x; i) F  m+ ?1 ^% d' v
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;% v6 F" _; ?  j4 ^& P  m$ I% L
                        });1 a) Q! w% m/ K$ r

/ r. ~0 w$ p3 b  w5 s: Q& z                std::generate(vec2.begin(), vec2.end(), []() {( d3 m$ C) T, a" @
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;: M% H, q% a, T. P
                        });
( r& h9 r) S! L) d& R) ]6 |! v6 z9 S1 X& f
                for (size_t jj = 0; jj < vec1.size(); jj++)
7 F. i4 ?) d5 S/ \                {, |# x1 V$ U* N
                        b1[jj] = vec1[jj];
9 y) T4 Z9 B! K                }' o+ v$ r& P* Q; p$ @
! f8 O" Y6 m7 q3 P: O
                for (size_t jj = 0; jj < vec2.size(); jj++)
3 z- I+ y  R1 ?- n* v                {1 [( l2 `- c; U& `: |! G
                        b2[jj] = vec2[jj];' I; @2 p& u" i& G
                }. W( [. x4 \" ?, ~" L

- y# |+ w2 b- _+ K6 `9 I' `# H                //Method - 1  N=100000 247s  
0 M, y. I7 ]; V, `/ b                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);% _2 R( V  Z$ r
                                ( |/ }" `& M6 [. Q2 q5 G: M
                //Method - 2  N=100000  237s
5 o- Y, Z' t1 {; l                /*
& E0 p& ]$ `! G0 [1 g* k                for (int jj = 0; jj < N ; jj++)
. M# S+ U/ ^6 E2 }+ y! C                {
3 G6 F3 t2 d; W$ D: ^1 m                        fresult += vec1[jj] * vec2[jj];
1 F+ W6 H* [' z4 q4 [& Y: h                }8 C6 l' n4 G6 p# O
                */0 I% J+ ]# U6 C/ H/ m
                                
! M6 _) t' s* L7 H3 S8 C                //Method - 3  N=100000 204s
0 ^3 e3 S# j4 D, I" Z1 R+ x                /*
8 ]7 R9 F$ U4 w# B9 B                for (int jj = 0; jj < N; jj++)' w4 O& ~5 R' z1 o9 h
                {
: p$ B* |3 p' p- v                        fresult += b1[jj] * b2[jj];7 M4 p7 g2 a: B. `
                }
6 E/ U2 L3 V% T) `4 P  V                */
9 `, P1 ]: H. E2 y) [8 \+ O- \3 H7 d+ P1 @  e0 _9 M  u- g
                //Method - 4   202s2 [9 z6 \4 B; U- X$ k$ D+ p
                /*# G# j* {+ I, u) q1 t
                for (int jj = 0; jj < N; jj++)/ B2 J; ?# b) V( L7 F- Y# [
                {
' F, l  N9 P8 h) w/ U! T8 ?4 h                        , y# {% U/ O. }
                }
& Z% w1 Q  X" l$ |" W2 R% q                */, d3 B& h0 D8 R/ n) ?1 P2 I1 V8 u2 X
                //comment out all methods, N=100000  202s                " k4 X! R( w0 g8 h
        }
5 l# v6 |' G: Q1 s$ x) @0 y7 Y, Z; n
+ S. [) j& ~2 I0 h        delete []b1;
$ p9 P3 n0 Q, {' |8 @        delete []b2;
: }0 x' b1 X* N* s

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?/ U- I; ]6 b3 X
- y+ Z( O' W+ D/ ^, e' t
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?7 f/ z+ {# y& O* `6 F8 B

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15  J4 D. @6 w8 s" c
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?, z4 P- z# y9 |$ \0 s9 }

. x6 @5 \4 k: t& B& B! a你第二个试验里面的j在循环里面又重新定义 ...
8 v7 ]0 K8 u, Z6 O7 u8 Z
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
! R  [1 I; t& o
$ Z* t, d7 ?" @5 f* z不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
4 @6 O$ O* ]5 ~6 n内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL0 M7 b( ?$ ?5 z: i4 Z& c5 ^
8 i% f5 E# _# t8 o
不和它 ...
: f" ^  g9 a& p6 H+ a
( n& F3 d# I' t; u5 I, ?
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。$ q% ]( q" [+ |2 g
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54. i$ m5 Z: z' \1 e
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; B- e5 {$ }, o5 I. y( M8 y{
. H2 c: \3 z) s& c9 x        comp temp, xtimesy;

" u- F% Q5 D. ]9 G* k1 g# l这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
8 d% N" _. v9 p" V& N0 ^) g内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?  R: @4 Y5 |5 k2 t/ ]2 [. X; E9 s4 Y
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
; {) I. |  C% f# C) s. t7 {理了理思路,重新做了一个测试。3 I$ `4 }7 ]- `' ~1 l9 V
做了两个 vector 和 两个 float *, 都长 100000& {! F( J" @2 b: m1 I  G( ~4 V
外循环 6000,里面先做随 ...
, w4 ]6 ~; l# d0 H
这个时间是从哪里开始算的?' W, ^9 d7 J/ k' Z8 Z8 A; v- a7 }
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
, }, _. S( D9 U+ F按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
" L, y6 z8 F% ^& y这个时间是从哪里开始算的?1 a' C+ ], s4 c1 z5 E
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

7 ]* y( h/ I4 U; {2 \我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。- N# `" r0 Q  C5 _8 M; N) C2 p8 l% s
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。' i0 l) x# F) q9 `; i
与此对应用数组(指针)花了2S
( Z& |( n6 N  V; `1 w* T你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
3 {. @- q7 t: X! O! w; m7 \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; v' y1 m& g4 Z8 V- d{
6 l: z' {' i4 z0 [: T        comp temp, xtimesy;

; a# G# G$ }0 @0 @( F; K" J# y! G我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗7 u% Q& N! e; j4 ~. y: A2 U# L

; Q5 `' t% n# P1 t
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:291 X) \- D( l: }( C5 m4 c! x0 p  {
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
4 c7 I( w+ O8 ^1 d! H# y  U3 N& l: q6 k  X/ F% P+ t" D
...

2 ~- L- {$ t( c1 d- W; U) r你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。+ i; _, T1 l$ x
* {* |: X0 l5 j7 G( u
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
# m4 h$ b0 u7 J) ]& C) J8 j$ s' \) L* n+ U& Q/ v, A2 c3 k
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
" r1 \8 N) S+ \9 v4 s9 d0 k2 i有空时我会试试 SIMD和并行,看看能提高多少。
* m+ m* f4 l8 v! H) T过去7、8 年没有正经用C++ 写过东西,没有 sense 了
- z- y9 ~- p# c' f! [2 {0 E谢谢大家的讨论,I learded a lot.  红包已发  + K7 F, D+ B  P8 n! b1 v
7 `6 G' e0 _9 w- ~( p/ p8 P

9 @" P) g1 a+ U/ k, Z# B, m* d' k. d$ {7 y* F9 D

, Y/ h. ~4 G; A1 d




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