爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
9 p0 I" M0 ~* u) P: L, D% p6 E/ ~9 r
6 x6 }$ H% C, z% r/ J: h' g+ C自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
* Y" J3 B' a" W" O) Y* b7 w; d) O6 J7 ^3 |( ]1 G5 w0 \/ \
速度优化问题真的很有意思啊。
; i, H) l3 L- V! i
9 ^7 e9 e% M5 A- s( g欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
* ?' W0 ~1 C! _, j把代码贴上来看看?5 c8 W. q3 g+ D- N7 k: |7 D" q
7 k0 w6 n" P5 t2 P
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
8 x2 Q- c4 Z6 d, s
数值分析 发表于 2022-9-24 23:04
6 I5 \1 U6 n3 W4 _4 K拉下来?拉多少?
" G9 `) @5 A" z5 k! u3 |: J/ P$ x: ^把代码贴上来看看?
- C" K7 j3 z* J( _
1 R' M' j& t# z- X( D6 ~
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ T2 R3 R; T7 a% D# o& j/ j
{
$ j- J% i; O: x9 I: {8 ^        comp temp, xtimesy;
! ^7 {+ M0 |! V" r# s( ]        xtimesy.re = 0;2 @7 k% d6 m: S( T
        xtimesy.im = 0;# T) K9 ]# e$ L5 B$ P
        int j0 = lenB - 1;
- B3 E5 O6 U; l* a5 N* k; K        int    i, j, i1, reali;
- c9 U9 U7 q6 @" `; }2 x        if (lenA % 2 == 1)
* |7 {4 i. j: ~                reali = lenA + 1;
) u3 o7 D# W8 L        else
% _" s/ }0 A" C7 `                reali = lenA;; }; V3 b$ K# K9 q  H1 p: B
        reali /= 2;3 a) X7 B: m* `( O/ |* ]" n0 u/ ]
- c8 k. Q- I+ J& b
        int nconv = reali + lenB;- Z% S, R" M0 H, J6 n8 D
        //#pragma omp parallel for
; _7 b$ _8 N. R: d  T        for (i = reali; i < nconv; i++)) P  s* e/ C, Y3 f6 N
        {. C/ i$ v" v5 o7 m: v* u
                temp.re = 0;' S& b$ A+ ?3 n- S5 f/ D
                temp.im = 0;1 Z, h$ D/ h% m+ F
                i1 = i;
4 p. n9 y7 J& p                for (j = j0; j >= 0; j--)
! C3 q* V9 X8 o$ d0 Z# O" ^; }0 h                {7 L) @( B5 K& V* H
                        /* floating date operation */& V+ ]7 l0 K" @5 X
                }

8 m$ ?7 y2 G5 E  @  Z- B& Y* E        }
" |; ]7 j- b! e! T* e; e( J8 A}. n4 Q& i8 H2 p* v" w

, D4 _  W. [+ i: O+ Gxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
9 x1 n: G  g9 c( {5 c5 K$ q" B7 Z  U! }# o" I; L3 N
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
2 f0 L8 d" [2 h7 b现在call xcorr 100次,耗时78s.
% h9 q9 i7 |/ h- e- t2 Z* f3 g* T5 r; u1 K9 j. |' ?! e$ Q  O
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
! S+ r6 j0 d5 p) D8 B9 ?& z1 h! _2 t# O! L4 }) W9 c

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:339 J# x9 }% {0 C
Maybe Debug mode?
6 z6 T3 |5 @( }" Q4 \; X
: K: z! h1 D! Q4 f1 |
不应该,看我上面的回复。: j0 c% |  O) \) b( ^7 Y* f

8 V/ d- ?- w& x/ n5 T0 v2 {我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
1 x. N* t% [: [
雷达 发表于 2022-9-24 23:54
4 ]5 e2 f" J/ a  }void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
2 |% h4 A! w  ?5 A{
8 E$ x5 u. g( s8 ?  C* V        comp temp, xtimesy;
1 H2 u4 L  j$ E# j# O- B  ^# B2 b

! G* ?4 [2 l8 }1 R1 b* a* a3 M这个不是这么比的吧。。。' X) ^- Q7 k! w* p: q

$ [2 Z  h& ]8 S7 c您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
. o3 L5 Z2 |: h+ U: G% H9 e5 e$ Z/ Z, N
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
" u$ l3 Y. |3 S
数值分析 发表于 2022-9-25 00:20+ A! A5 ]8 N+ i8 F
这个不是这么比的吧。。。
0 y& w4 z" B7 @3 v9 F5 Z3 t& s! f; P$ z# N' d* q9 Z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

/ T3 u2 u2 a; n6 u9 b2 T3 D2 X/ ?) w3 @" \  @. D
有道理。7 [3 Q. v! p! o- B
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
6 y8 W! H3 e2 L3 H. c$ F' C$ C; |6 M5 ]! T& M. K7 V
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
4 f4 I9 u0 n: A% d! P' Q有道理。
; ]! g+ Q9 y+ T1 B. c8 ]3 R所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
" h! v# f0 ~- }4 m: ]' ]+ T# a
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多; E/ u2 }$ `$ U4 o  o
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:203 l/ p8 H6 x5 y
这个不是这么比的吧。。。
2 S  T( A, L$ T, P7 m
0 C% d% A/ S. {# O4 {, z( ]$ u# M8 K您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

" K1 {2 p' T4 i$ u. H  M+ L- p6 J
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 5 m. T6 W5 F/ n' ~+ p
沉宝 发表于 2022-9-25 01:48" A. F: V, O" f
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

1 u7 I: B% u+ E
) Y* L+ q" Y8 M% `6 E; A; B5 b是的,兄台说的对。
, j) R  G! U1 N- j2 U3 L  C* z  h$ n! L3 G
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
+ H- c3 B3 ]9 V7 h( c# _- V
, S" W$ |1 X; Y- I$ L. q* X) H雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
6 f- Y0 ]- A  I1 }/ {, D
7 ]& L0 G1 Y6 T- ]5 L' K8 l; O5 y% ^比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
/ _5 r3 T5 T& S( C6 p% O  V" B7 V2 ?" }* I1 W2 S
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ! q5 ~5 Y& [6 \
沉宝 发表于 2022-9-25 01:27! a- ^* _$ K6 ~. e; t0 Q
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

  u  z' r: X$ ]) m, p# y' X/ o6 H7 J  h- w  \- j* M
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
8 H/ p3 ?8 O9 ~+ H( H% T0 C( U# F; z, E& ~" a" R2 X
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
4 X/ m% U- X( e; i1 Y又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

6 P5 y* e) i$ n6 Z$ i: R时间差一倍的结果可以接受。
0 S7 m" o* ^) }( X$ n! X% y8 S* R) f# o$ y
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 5 F+ U9 E7 R  @+ |5 |
雷达 发表于 2022-9-25 04:47$ ~" h  n& p; b1 @5 r: r" q
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

' v7 p/ x9 k6 O' z6 a; G! J3 `
, d) m5 k& ^( d3 x7 y
9 m* I( `0 t8 `1 O! K  L0 a5 ^! k6 A$ m0 e8 c' Z) O5 k
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 b: [/ g( G& B! _/ A; N
数值分析 发表于 2022-9-25 14:588 x4 `; H& }; K' r2 V$ Q. w6 ^
能不能把这个也贴上来,看看和上一个有什么不同?

5 \# a+ X9 A$ `" h理了理思路,重新做了一个测试。
% O$ ~2 Q) \% m做了两个 vector 和 两个 float *, 都长 1000009 t/ V9 L( }7 q# T+ k
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
3 }. G, v$ r3 B; j6 u$ t, [/ o, k. p$ r8 O  e6 m: R3 V5 z
内循环试了4种方法,9 t& R" S5 i9 s' U- }
1. 直接调用 vector inner_product 247s
4 }* H- ~% `6 v# d  |2. vector 循环点乘累加 237s
9 o5 I; f4 I; o3. float * 循环点乘累加 204s
9 D2 z3 l/ U8 O, D% S4. 空循环 100000 次 202s
6 B( [& D3 x- t, r5 U' s: l. G* S( A* \6 [+ n
不做内循环 200s
5 ~' T9 d6 |( I$ R0 H8 O
3 P: T4 V" I5 a9 P# t" t! J; C你昨天说的对,内循环本身占比是很小的,大头在其他处理。
& q6 B) d8 ^5 W7 s8 _另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。+ h5 G$ q& ?, @" ~3 a/ S
0 Y( G! n+ n6 V  z+ V
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% L6 C' P! E+ x

) \3 u8 k  [* @$ b) O(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL): K3 ?3 j) ]0 g4 w$ \$ g

2 O% U8 u  n- M( s- H
        std::vector < float > vec1(N);) l' ^3 D2 c" F8 T( _8 T, F# A! j
        std::vector < float > vec2(N);
/ U) O- C% L' w8 ]        float* b1 = new float[N];
3 f+ y  J0 g9 x& ^* a        float* b2 = new float[N];
& z5 W- l! A3 V/ ~5 r  z, g) r0 v# c- V% J
        for (int j = 0; j < 6000; j++)
" T3 ?  l0 e5 d8 |" c* L        {
. V% x( @1 l7 A' F  ?                std::generate(vec1.begin(), vec1.end(), []() {  H" m+ u7 G1 P& s6 D& R1 b1 ]% ^
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;2 y! H  J7 t, ?! E2 D+ T1 @
                        });
# n' }2 f* W, }$ }% O, K: M- d4 z# Q, n& y2 K
                std::generate(vec2.begin(), vec2.end(), []() {
( a8 I6 w9 Z0 M, u7 T# {                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
6 b  V/ p% J) j3 {) L6 e. L                        });2 ]! K/ Y8 P! t# V

+ M. g! N. {% a# |) j0 ^                for (size_t jj = 0; jj < vec1.size(); jj++)/ z/ h0 x# N4 C& }
                {
) u3 f1 N3 q# s                        b1[jj] = vec1[jj];
$ w2 V7 x9 n+ ?: _                }! ^- u  f- p1 e
" L1 Z% s# \/ W% W
                for (size_t jj = 0; jj < vec2.size(); jj++)' L. l4 W% ~) ]5 g
                {% J- S! L1 C* F% Q- j
                        b2[jj] = vec2[jj];
; W) f. q6 O* j+ ]                }9 g" K1 o8 X3 |5 ]( f6 e) X7 ?$ l

8 I$ ]; `  Q$ A! f                //Method - 1  N=100000 247s  ' x, ]! q) G  s- q; z  W9 Z
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);8 ?' {3 e; U8 a2 N2 ~6 U; \2 H
                                
/ q4 ~7 n$ j3 K* L! e4 g1 o  h) S                //Method - 2  N=100000  237s" _; O" Q6 w+ w3 m" S! V! _
                /*
/ C) }3 \1 l" w% R* t$ R" u                for (int jj = 0; jj < N ; jj++)
9 s9 ~  M8 z' V6 N& L                {& q; f0 n$ A* I, c" w* S# d" U
                        fresult += vec1[jj] * vec2[jj];
) `' ?" i2 S% n) J- Z                }* t; ]; p9 p2 z8 n& t+ h: i
                */
: J. D4 Y% b3 q! F                                
$ h2 ?! {0 W8 a& Q9 z' I                //Method - 3  N=100000 204s
& p, p/ D/ q; N) b                /*
- {- e; L3 ^2 t' e3 a4 s0 r/ G" W                for (int jj = 0; jj < N; jj++)4 y* ^6 d% b+ Y6 ~5 O
                {
* t5 _3 h8 O2 Q, l5 }9 L6 x, u                        fresult += b1[jj] * b2[jj];
) `( t3 Q6 x3 W$ @5 E! a& W8 G& A; [                }9 ]( @: N/ e$ b; r
                */
, R1 e( _6 X6 X0 b6 h3 u& [2 l5 ~* m) O; |( q1 P
                //Method - 4   202s; I5 e1 n2 g' P- |" G) G! g" o. F
                /*3 f) {" v" K4 [) o
                for (int jj = 0; jj < N; jj++)
& U' T' w" I4 N4 ]                {+ z4 F6 Q: e( L
                        
" _0 i1 Y7 s9 U1 ~( W                }1 e. g; j: x+ X1 H# n
                */0 O% T2 G8 J7 X5 T: P! S
                //comment out all methods, N=100000  202s                8 \3 k" s# u! y# t8 \# ~
        }3 k, z# `1 c9 a: Q# e# x8 V  j

: R; H' X7 D, A$ n& M        delete []b1;5 h# |  U% O" g+ B  b0 C
        delete []b2;
( s1 d$ m+ E  k1 f7 x' p( @

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
$ @$ }1 N2 K: I1 ^, G
# V6 T% `8 b8 K你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
; U4 {8 D5 e% l
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:157 v/ d& N% ]# [# Z+ k
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
9 Q* S- q( k% o9 q" j+ g% {8 x. y% Q& y# ^) Z/ S- D
你第二个试验里面的j在循环里面又重新定义 ...

5 D3 E. O7 h9 M内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
2 g9 Z2 \% C( a  e* Z3 j+ }- Z0 X% w- S
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
0 m* p- k* Q; s6 v* v内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) ^# `% s4 B. L" Q, h. b2 [
% i! c5 G2 z. m) d' O
不和它 ...

( q" ?# }3 Y; K- d, C! I. A! Z
  ~; o9 I' t4 I8 r/ r- }+ ~不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
' H  p' [! [5 w0 v7 M0 k后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
0 Z. q' d% ^( D* T& gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)$ N- A7 Q7 E4 v: a7 }/ q
{
8 A4 {. m% i' l) \/ H3 V        comp temp, xtimesy;
5 }) ~, Z, Q  F# K& B4 ^4 B$ @8 h7 J7 _
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
/ a4 U: E" t3 K% E3 h. \内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?7 i5 @/ g& P3 v( l/ I/ X
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
7 ~" U" w. Q; T# J% I/ Q理了理思路,重新做了一个测试。
2 i5 l/ p7 F6 c+ i9 z- {- k0 ?做了两个 vector 和 两个 float *, 都长 100000) t0 P* z1 _3 }* t
外循环 6000,里面先做随 ...
  V: @3 q0 C1 }: v/ o" f  Z+ ]4 ?
这个时间是从哪里开始算的?, n- H3 r( F3 `6 k. S; S, [
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。& z! F& c- p  X$ J! c+ s0 t; a
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
4 j6 q& ]' l& t$ V' B6 \这个时间是从哪里开始算的?) @% D1 n2 u( ]/ @0 ?
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
4 }6 a2 I& R% V7 t- }, O
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。8 X% h! y: x; i8 r
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 T& ]% c: E5 B2 l1 W
与此对应用数组(指针)花了2S8 G' R( s6 L. t: ]7 D! r4 g" x
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
( [& x7 j1 t% w1 f- hvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) J# g0 F3 |7 c* `5 V- S{* A5 w, j  f( r8 m  R
        comp temp, xtimesy;

% H8 o+ k" C$ n$ p3 ]0 Z我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗1 f5 P$ Q; a4 ^  F2 m0 v

1 T4 d4 }6 q1 ~5 m
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:293 B3 Z# [: W" Y/ J2 q+ D
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗; w  y& V% S2 }5 O( ?
0 l! A8 M- K0 P' Q$ o7 D% f
...

0 y6 A) e7 T/ E3 ?$ j你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。. ?8 u+ Y* j0 j; J. k& W( t

9 V2 J7 ~) V1 W1 f雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 1 z* Y: g& r2 Q
$ U2 Q% b/ b7 w' ?0 p
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
9 f1 X3 e" l6 w4 ?( o9 K, w: N2 u有空时我会试试 SIMD和并行,看看能提高多少。
8 K9 ]1 u$ U. t) E6 @过去7、8 年没有正经用C++ 写过东西,没有 sense 了
( ^" J& G3 z# s$ r0 F谢谢大家的讨论,I learded a lot.  红包已发  
: p5 E$ l/ U/ V8 ]8 _7 N
# C4 C7 @8 z& {) d# ^/ a- r& A( O4 e3 V$ A) M+ K" L' u# Z' s

. W# Z5 X7 r5 V% Y/ Q4 ?% e% l  ]" x0 q, l  S) C  A





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