爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
. a) i4 J+ h4 @( V$ _
' B9 q% g$ F9 S: i, q8 X2 x7 y自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
4 a! K+ H0 d9 _7 W' q7 k. x- _' W3 E" _2 R& l9 P
速度优化问题真的很有意思啊。! ]# G. i1 P" G

4 ?2 _! ^2 t2 i& }欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?* u. O5 w+ w5 l5 ^" T$ P' ?$ |* m
把代码贴上来看看?; C# d6 X8 Q: c9 ]1 @1 {
6 {3 x! w' G+ v) Y! Y
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
5 A3 M  B# W; b, V( W
数值分析 发表于 2022-9-24 23:04. M" {, J1 t  ]5 S2 p, Y
拉下来?拉多少?
6 ?) `+ L; X# w3 h  f0 W0 I* ^把代码贴上来看看?

! h( W$ N+ o( |/ F7 S7 d
/ M, z% [9 F& n1 r4 Q+ W2 ?1 yvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 G* ~; }) c; O% ~! j
{
+ I6 ?2 q9 n  K. P8 U        comp temp, xtimesy;) q# K3 p8 D7 W  K8 B5 S0 S6 [/ u" |- m2 E
        xtimesy.re = 0;
. l! L) f, E  c3 _  m7 s3 D        xtimesy.im = 0;
% h2 [# ]9 W4 |% v& N        int j0 = lenB - 1;
8 D% H3 O& g3 ~" Z( K! G        int    i, j, i1, reali;  a" M) u+ U9 b3 i
        if (lenA % 2 == 1). a7 f3 v2 s, R8 N: [3 K( j
                reali = lenA + 1;
! `$ r9 d$ ?' K, V; @2 y/ x3 {        else4 Y6 ?0 i9 C# K8 H* N+ V
                reali = lenA;5 |" i- `4 Y8 y5 K, B& ^7 {  H. C
        reali /= 2;1 O) s- t' H- y1 K
7 K. M, ]1 I) s; o
        int nconv = reali + lenB;+ Q. C7 N; s: Y1 N( C5 \
        //#pragma omp parallel for
% Q5 K) X% f' i( X; g) d        for (i = reali; i < nconv; i++)$ H# V2 U, w! Y" b( q4 i
        {
- W  B# O# @9 z; j! Y3 }1 [                temp.re = 0;2 Z5 D" {1 Q/ f
                temp.im = 0;2 M& K4 k+ ]+ {, K! `$ G
                i1 = i;. b6 Z) g* Y' |9 J. i( D
                for (j = j0; j >= 0; j--)
- u6 g5 J' a2 Q  t' E" [! W2 L                {5 T1 c- ^/ M0 C. Z5 `9 I7 F
                        /* floating date operation */
' D/ E( M+ }' O) j# C$ d# Y& \                }

! M% j' ^: y4 l! e4 a9 B- K        }
/ O. f) K8 G& w0 T}+ z: G( d8 U% `5 Q  Y# X. t
5 e8 a& }& b0 q' s
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
2 E* U! Y3 f, J! e' F; F+ N9 W3 y8 \- e
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。! v. b+ D! @+ I# y- S9 Q
现在call xcorr 100次,耗时78s.
1 J, y' [1 W; ]2 o
. V- h0 Z. j$ f. }如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. * ^' _5 s# c# R$ \
8 o5 m, D' G% J4 X

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
  \; h0 V; l' ^* Y5 E1 @Maybe Debug mode?
' Q2 q3 I9 l, W0 s$ j4 |$ E  K9 ?
( O, q: ^- q# f4 L" p
不应该,看我上面的回复。
' l: Q; U/ p, ~( i5 O8 ~/ ]( E" R& X3 Q0 Y
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
) b! w% j8 I3 ^3 h& B
雷达 发表于 2022-9-24 23:54
- M8 V* Z6 M8 M. }4 {void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ o! P" A) ?. D3 u6 y4 u{
/ t. S' ]+ C$ `% f( s        comp temp, xtimesy;
% Y: I4 b. |3 ]$ {$ O! t1 k$ T

2 M9 B0 q+ Y' u5 u# J8 z这个不是这么比的吧。。。
% D2 i5 i. b2 H, v# _- m/ u
# K4 i, D, L: Y5 |; j: |您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。, n9 [& E3 u0 ^8 [' c9 b" K2 n- e% `
0 V, T- i7 R5 a2 c! M
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
( X  N5 l# f: B
数值分析 发表于 2022-9-25 00:202 q/ G0 I; ^6 K  M/ M
这个不是这么比的吧。。。
7 c3 Q6 n9 m  Q4 \% a& p0 N$ I- X0 G7 f6 \( B
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

6 A# U; G9 I, S; K" ?+ \1 E: n
. e" i& G" b9 _) }) A有道理。
& b4 h' N$ c0 J; k$ g' L所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。  x. O5 T2 d6 l' ]
  [, Y/ D/ R' P: S. o
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:460 @7 r4 a& |! V0 _, g1 v8 d) O9 J
有道理。: y. V5 b; a* S$ N
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
* F! r% Y! q1 ^$ w; t
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多9 J4 q8 u- {% G! @( O
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20$ n4 D2 w: O# a" {" x; H2 h
这个不是这么比的吧。。。% L) R* l0 p7 t* P9 P+ ?) q

* q" q! k( d7 \. I; H& T. F您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
, S9 n) u* G& X2 x2 o6 ~0 Q0 Z
  p. F5 G- O  W; N. i0 r
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 7 z0 @" u6 }* Z$ a1 O1 t1 ]
沉宝 发表于 2022-9-25 01:482 ?8 s$ J* M( R, K7 G$ G" B9 Z7 N/ r/ E
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

$ h4 `: M6 P3 F; |% T* G: b# O/ Y) H! Q; n8 l. z
是的,兄台说的对。+ m  }5 x2 w2 m% R' ~
8 N. d+ v9 r" Z7 p+ H, Q' V
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。4 P/ B& _& ~% \! P- N& S, W7 m
0 B6 l7 R- b5 z1 t6 u, Q
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
+ A+ I6 B( Q; P2 [4 T5 o
5 l, ], u3 s: U( n比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
0 G3 q7 k7 x) b* d2 i- F1 {8 Y% a( {2 k2 D6 p+ V4 }/ Z/ K
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
. b, T0 }* d. a- S
沉宝 发表于 2022-9-25 01:27
4 h  h& ?+ {1 {" C4 ]" R- r  v- s你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

- Z' m9 Z: Q* [& c
" c0 }. a# o$ d0 ~% Y( Z又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。4 j  a% e, ]  B' O' C+ l
! G  V! i2 T% L+ E8 T& o2 i
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
: w0 ^( k- Y8 i又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
; g, b/ q4 g( m4 i- p
时间差一倍的结果可以接受。
1 F4 o6 f7 P7 u" l$ Q/ b( t5 F+ e$ r, X+ C+ w3 [' m
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 9 C: B! h* `0 h& t4 Y0 u/ I9 w
雷达 发表于 2022-9-25 04:479 z3 J4 p& {9 t7 v$ H
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
$ v# P* H+ b- |$ G

0 f- L$ O# X5 ^6 I* c1 k& s5 P4 s5 K, W! m9 Y  x6 n8 p; V: B- z
9 f  M1 r; E0 ]0 s
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
/ K  c6 H2 Y% M/ s
数值分析 发表于 2022-9-25 14:58
* W7 O6 B& B6 z1 G能不能把这个也贴上来,看看和上一个有什么不同?
& c6 f  q" p: V
理了理思路,重新做了一个测试。* k3 d) O5 h9 N+ t5 w* e, }& u
做了两个 vector 和 两个 float *, 都长 100000
- i# T) a" ~" r外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.4 U$ [2 ]. q! u* e3 i+ O& C

- o! E4 b% P- \, X9 ]0 _, }内循环试了4种方法,9 u3 h8 [- L* m7 m) `% {
1. 直接调用 vector inner_product 247s : l* @  |/ Q, T  B  ?
2. vector 循环点乘累加 237s
4 w/ u& b6 K. ~2 H: W9 u( n* N! ?9 G) D8 D3. float * 循环点乘累加 204s
8 A$ a9 |" M2 f4. 空循环 100000 次 202s/ B0 C7 E( A" w$ z% {9 E, _, D
+ d; U4 ?( f6 w) R/ t0 v) T
不做内循环 200s
  F$ ]5 `- E! d' c
8 H: H$ v6 w! g0 r! \# m你昨天说的对,内循环本身占比是很小的,大头在其他处理。
* R$ R4 ^3 l! T3 [' h" h4 \另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
1 m) Y0 y/ J$ \) m" M5 W+ I  `: g# Y, N
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)6 T. M* W0 W% q9 u4 y* e9 K

4 U5 T, H# ?7 U' {+ n. o  ~2 |(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)% C" ]" N+ y/ f3 J7 {5 y, k
& z1 [- f# A% D2 q" f$ {: v
        std::vector < float > vec1(N);
- @. X* y5 z7 |        std::vector < float > vec2(N);# a, c, s# }' ~
        float* b1 = new float[N];
- a  J) E  [3 o        float* b2 = new float[N];
2 F+ N) D- a9 T  ]0 K& M; L. Q% B+ u( H
        for (int j = 0; j < 6000; j++)
/ n* n- x4 x  J, T/ D        {, E( h4 e5 \/ O1 u3 p& J: [
                std::generate(vec1.begin(), vec1.end(), []() {
" ^8 X" E( n. ^8 L$ x% p                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
6 d- V8 _4 M5 F( Q0 b$ Q# _                        });5 w6 _5 ~5 Y- Q. D
; @( v5 x/ W- n" o
                std::generate(vec2.begin(), vec2.end(), []() {
$ ~; u6 m( }5 q$ r' Q                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;' D1 }8 Z% w7 ~! r' g, }
                        });
" L3 F0 c+ o. R5 i
/ e# E4 R3 N. A8 v0 s                for (size_t jj = 0; jj < vec1.size(); jj++)
  ~& y) r+ [2 N- h! r# G                {
) K) l& F9 \: }( ?                        b1[jj] = vec1[jj];0 r6 }/ \' s( p7 M% a7 T
                }
$ t, ~+ p/ b; x4 n( g5 G( d2 v8 ]" C9 @* z" v8 W9 U2 g* @$ Y' c; ~
                for (size_t jj = 0; jj < vec2.size(); jj++)# X6 e5 M! @) A+ M" @
                {
7 s+ K2 d! |- n3 C! c$ Q- Q) ]                        b2[jj] = vec2[jj];
, Z9 g6 ^( ?) q- J$ B                }
; n4 a7 J  e9 g5 \$ _5 q$ A7 p2 f2 h7 I2 V9 d
                //Method - 1  N=100000 247s  # J, g; l( D# p2 b9 f& i
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);3 p  f0 W# }% o  `9 [, a2 P+ y
                                ( t: K6 ~( d- V7 t
                //Method - 2  N=100000  237s
8 |# x8 o' u) I/ T! z' a- N                /*# U$ Z+ O, C7 w* ?0 ]
                for (int jj = 0; jj < N ; jj++)
- n% t# l3 E* X& O* T                {
9 O' Z. C# n$ h6 ?2 g$ _                        fresult += vec1[jj] * vec2[jj];
# b/ w4 @+ r5 w4 E  o! Q7 Y" `$ _                }
  ~  O1 U9 P* @' J                */
; w3 ~/ r' d* w8 M) U! ?                                - }! ?7 Z9 [8 r
                //Method - 3  N=100000 204s; K2 k7 p, N! M3 P
                /*6 l; V/ [  G3 T8 `5 Z+ Z
                for (int jj = 0; jj < N; jj++): J' L0 [! f. g$ Y4 ?) j
                {, z8 X, i* D& i5 c2 p" y" k
                        fresult += b1[jj] * b2[jj];1 L# A8 g2 F) v8 q) k1 e, g8 J
                }) m5 i8 q$ @) a( d" L" o* R6 y. G' h
                */
9 f8 l6 S/ a! D  |: G6 _. T! N! i5 ~# y! v7 R1 }
                //Method - 4   202s. E" X( K, `( c' k6 g
                /*# D0 V& a  k% \2 L) x* d
                for (int jj = 0; jj < N; jj++)) [' V) n) U' l
                {" h9 L( K+ _* @& {. K
                        7 `9 [8 |8 y9 n
                }
( S. R# F: O- A                */! I: ]8 O8 F% u# W( @3 D+ @, m2 \
                //comment out all methods, N=100000  202s                / u* r1 X! p8 X2 r: x/ G/ V
        }* A- `# x$ I. C0 r

! \# }$ ^; \9 |( j! z8 f        delete []b1;
8 l5 y0 \' @! y$ C- a6 D        delete []b2;
1 {; A& |3 U7 Q0 X7 ~7 A' o% Y# P

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?: h" |- K2 j0 O. Q( u/ N6 s( u8 g
# n0 }3 N) w3 A- l' t
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?0 l( K8 z) C" W7 J" z; {6 Z( h

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
1 |2 O3 X" @4 u4 Q# D4 K, N9 n) X5 ?瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
3 Y% f% i' o4 B) U' c/ {+ N
" P0 n& C' F" ?- W5 [; ~. ]  j你第二个试验里面的j在循环里面又重新定义 ...
1 \+ r( C  `  Q/ j
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. L0 l0 W2 C1 ]7 l2 I! B

* r- g2 Q* y9 ^, Z不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16" C. |" y* x$ H; N; B  U2 e/ ]7 b0 Z
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
. }5 `& I) t1 v! P7 j6 u$ ~- i) a: r2 q6 J: p: m- o5 G' P! f
不和它 ...

, p$ z+ K% w  R& T7 v' T
6 ?  F7 X0 J$ x* V( G不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
6 P. h0 }! c& W; S1 a- P后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54$ K- Y7 z4 X: t3 v& n7 U
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( d; q3 Q3 m6 F
{
- `* x% w& v' p$ ]7 S' l        comp temp, xtimesy;

5 z  P" [" s4 ~9 e这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。% w7 D, z, @; [  \8 P5 e3 q
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?/ N# ~6 E- n& t3 t8 K
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
* h9 i) D) {( i. ^# T. ?$ L! S理了理思路,重新做了一个测试。0 [" p) |; S2 i" B3 Q! B3 Q& @
做了两个 vector 和 两个 float *, 都长 100000$ N7 \# ^1 i. k/ N& r  F* Q
外循环 6000,里面先做随 ...

6 q, X! [9 |8 F$ j0 F& P" p这个时间是从哪里开始算的?
& Q$ N2 x) u5 G我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。6 s( i4 Y1 ]; k5 t
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39, P0 k- h1 m0 C
这个时间是从哪里开始算的?
4 t3 `! Z. a* m  x我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

/ V3 ]1 k0 Q1 C8 t* Y1 k我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
9 G2 k9 h0 m7 t" r. ^2 i你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。/ P9 e3 N& t2 S( _9 ?
与此对应用数组(指针)花了2S
! X/ A' G0 o+ ?* X7 F, D' k你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54) g  x9 n6 O" H. e8 @7 q
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB); S- w: S9 U# d1 r! `
{
* N% q/ Y/ `/ e        comp temp, xtimesy;

3 G9 s. W5 `9 h6 F  `5 o我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
: e, o  g8 u6 u4 c
3 F* [7 E" x& A+ Y3 W
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
' R5 ^1 ]$ [/ Z, N我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
2 X: Q; U. W% [
$ x$ N8 b& ^7 S2 T4 W+ f2 f+ m ...

; K1 A, [( M; q7 V' g& U2 d你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
' y6 c" g% S* c4 t+ ?" f' d
9 G4 x' ?) |; E0 g7 L3 q' w7 d3 i; n雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
% Y9 _% Y/ i8 }7 l$ q" D) y' h+ I# R
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
- o9 b/ Q2 @1 O' {% W; u6 n有空时我会试试 SIMD和并行,看看能提高多少。( j- j# f1 H, @1 `" z: o1 C; B
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 。, C5 ^/ W4 s/ Z
谢谢大家的讨论,I learded a lot.  红包已发  ( M; S+ j5 i- Z  B

( d: X  r! R5 G$ h  `/ d, D
; Y! v  }1 \; `6 ~  s7 f
! s$ w8 \6 I9 A8 Q5 @" i% ]5 b+ u8 D0 R- R: v





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