爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?' z+ l7 e# l4 q3 H0 C
$ p- ]* ?2 T! V7 Q; R
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。& R% o8 ^1 T3 o% d# z

1 S. V  c2 O8 i; u速度优化问题真的很有意思啊。
( u& V9 T" E8 O. _* E5 c7 K- V( w5 D# O3 B( [
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
$ f9 U7 s9 O3 E* A把代码贴上来看看?
, _  `9 A- f. O$ e; t+ L" Z7 E7 s% m, o: t
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 . g# z% A8 r( {) j6 Q. o
数值分析 发表于 2022-9-24 23:04# {) T- V7 V$ J5 N2 B
拉下来?拉多少?
1 R/ A3 P0 r3 J! O把代码贴上来看看?
+ C2 f* K3 p& [9 k; j
) C1 R9 y# e$ a0 |3 e- S: d1 O1 h
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
+ r! l, {: j% {. Y9 l{3 `+ t( ^" O4 z3 {9 m1 D( f3 H  `
        comp temp, xtimesy;# @7 c6 A0 a* U8 [2 j
        xtimesy.re = 0;
! d! U6 f+ b8 h( ]- g        xtimesy.im = 0;' f+ r& j6 M2 ?& I; s' U
        int j0 = lenB - 1;
1 l' b6 g, t6 x0 R  k        int    i, j, i1, reali;/ h" p+ I" z% ~. U3 O
        if (lenA % 2 == 1)
5 b& ], G1 d9 e. P5 Q                reali = lenA + 1;
4 l( m' W4 I7 V. I3 t2 r        else
- T7 @# }% i2 h                reali = lenA;  p* l2 `1 m% z/ C/ q/ i! r$ k" B6 f: V
        reali /= 2;
1 m) Z# m& U- H" v) k  ^
) T/ Z% V& E  `" A        int nconv = reali + lenB;
3 U% L' n5 X) b) i9 Y0 s0 n7 _9 M4 P        //#pragma omp parallel for
& P5 N* M7 V' U        for (i = reali; i < nconv; i++)
7 F2 i- J) R' D: \1 t) e# P+ K        {8 D$ m0 e  h1 o* x  f  e$ L, d: k. f
                temp.re = 0;- P  G7 `; z' m( I! @# N( i/ [
                temp.im = 0;
) n& V  C3 R# b8 ^$ |, f+ s                i1 = i;
$ Q( i0 l- i* G% Y                for (j = j0; j >= 0; j--)
3 X4 q  h$ f' ~$ S- Z2 ?5 k                {
2 `! t% z: r  ~& ?9 P7 }                        /* floating date operation */
- F$ R# \+ W+ M; I5 M( R                }

7 p  h7 N* m+ O" |        }: f" b' m/ r" @' S: h
}" y2 d! \0 T; s; x1 [
( D3 d. U) r; D  h6 w. @
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
& r: \$ m* Y: K! q) Z0 ], E* ]' \+ {2 l9 e4 V1 o4 e6 Q
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。7 t- j) H& B: X% s
现在call xcorr 100次,耗时78s.
7 _- ]; b! q5 Y% g  a  X6 K9 \$ q
+ d; @2 |3 Z3 D4 y# S5 ~如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. " ~) s/ u' c  `- N. A
. W  H, F0 y  p& g1 B& D

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33" O* i/ G: r5 s! p+ m
Maybe Debug mode?

0 t; K! W' M9 X) R5 {# w4 g7 _0 k& t' G6 U' a, T
不应该,看我上面的回复。
! e! X" \- X1 p' }& `' O  B$ T, I: U& o6 U+ v. P" U- h0 h+ g
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
, u' C1 ]$ l3 b9 T! O0 u' k
雷达 发表于 2022-9-24 23:548 [: h8 u$ k3 @# b# ~+ B0 Z
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB); v+ B& w4 |: o9 p; ~. o! U) m( x- p
{
9 d" _5 v0 P7 e        comp temp, xtimesy;
  H* V8 M, T' A! O+ K
; F. x7 _* Y9 P' ]0 E
这个不是这么比的吧。。。3 q8 ~* s& a5 {7 |3 `0 Y

  E2 \: J. M5 g* W5 \3 c您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。% @6 ?, L) m8 V$ x& j

0 d: ?8 i& P( U2 M9 c2 @) P而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 8 H# T- [. S2 l
数值分析 发表于 2022-9-25 00:20
1 j  M5 K$ Y" x; e6 A3 C这个不是这么比的吧。。。1 y; w- Y& L7 d
. I. f0 C; E7 H
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

  F; F! K1 _1 {5 g
; q( R/ `' O- s" E% a有道理。
; N2 U' f3 u, Z5 ]& K* L所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。$ K( P+ |6 H. Y4 a6 @

8 @  V5 `7 c0 v- `1 @* n1 n我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46# g# ^( `) l: Q
有道理。- M* s% d$ K; k! o9 T
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
" C3 E- ~" L- x. F; I5 c4 E" }# o1 }& u
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
7 }4 n4 s' h& z0 lWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20# z& v3 E. o- c6 N# }# h. J
这个不是这么比的吧。。。
0 c, Q1 c( J$ c) p  G- X  y! e3 e3 n3 E3 z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
6 O$ e9 ^% r0 j+ k5 x

% l" Z; F) D/ q4 f6 Z8 ]现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 $ L6 t. w# B+ v# D8 R
沉宝 发表于 2022-9-25 01:48! T% V, E$ v$ A8 l
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

2 a3 Q+ w4 l6 ~5 O' V/ Q' h3 [
# {4 p: {7 g4 m; F! ?4 q是的,兄台说的对。6 T$ i. b: A) C& Q
6 t& v! z$ m- k' n1 L" b  E
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
- {( }& e$ J8 ]3 C0 s$ F
: }* {0 F9 h5 U% D# j6 S) N) j雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
9 g6 n. [# \" m" N9 |$ g9 ]6 q: N' w0 \
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
$ x/ R/ h1 V% Z/ w! h% x" p& L3 r4 G* h0 j- [  M4 Z9 q
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 7 [+ e  ]. P+ v9 y) y6 L
沉宝 发表于 2022-9-25 01:27) P4 T9 ]$ D3 u
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
8 B, T) E4 l  A" K

7 i( \$ V  W  T& ^7 a2 j% h又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。  C# U) B2 u$ {6 b  ~/ Z$ b
2 ~" f0 ^6 T9 l3 x- {, S3 M
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:472 M# t& c7 L) h4 z& h
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
- S+ \+ |! x6 j! x5 D4 \) k# U
时间差一倍的结果可以接受。
! @0 T) _1 H- P5 v* q% H- L" V8 W' u% O/ u, _6 V' y
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ; Y- U4 a0 c5 v2 p
雷达 发表于 2022-9-25 04:474 T$ l! Y) D2 T4 ~+ z, B
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
9 g# K0 a4 \) {, V9 Q/ q1 D6 q

! i% M* U2 c5 G7 Y  s2 k
- J! M9 s7 J: f8 k. d" ?8 j# s' C- _$ ]
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 $ H2 y) o" ~# b
数值分析 发表于 2022-9-25 14:58) P. E/ B3 M4 d' v- h' c; Y. V
能不能把这个也贴上来,看看和上一个有什么不同?

( J/ J1 B) ~" T* T: [3 z理了理思路,重新做了一个测试。( H# P& [! q- s6 G) t/ B# n
做了两个 vector 和 两个 float *, 都长 1000008 }- z  h5 @# P* D1 z& p
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.9 S0 c. }% w4 F3 c$ A! P5 f
5 J* [8 i1 f. T: p0 A" Q$ m
内循环试了4种方法,
  e/ t) j. C" [1 _0 O1. 直接调用 vector inner_product 247s
2 f) m  x0 v* J1 M) d3 F# X2. vector 循环点乘累加 237s5 o" j" `! @) H. c1 c# u
3. float * 循环点乘累加 204s
5 e% V* j6 N, \2 d! ]1 m4. 空循环 100000 次 202s$ g2 J. V5 L+ w: j9 m  J

/ w2 c8 h3 ]. t) `  u+ R1 x9 Q$ {+ ?不做内循环 200s, d7 y7 _- \8 t1 Q/ H7 q( r+ d

4 D" C. S) J& I# B  o你昨天说的对,内循环本身占比是很小的,大头在其他处理。" N  F" N9 J# @& a5 X
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。: w" G; w- m) `* D7 h) o& S- P- [

5 s% P$ n" I$ |  u! V至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)3 @* G9 z$ T- w4 C1 ?/ g
1 U4 [7 \5 j; p/ \( ?7 Z
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
1 M. M3 P" K4 J+ L$ J- }6 v& l8 q- ^2 `. W) u8 S
        std::vector < float > vec1(N);
& [" Z9 y. G+ a. M1 t! H        std::vector < float > vec2(N);4 z- u5 j, C4 @0 w' e2 H
        float* b1 = new float[N];
/ A; K5 c3 m  ]* P; `        float* b2 = new float[N];
/ Q8 u2 R3 J* N: x5 R+ K
" U  P9 X9 f: g9 m        for (int j = 0; j < 6000; j++). T# _3 M/ D$ B- X" H9 d0 g& }
        {% `' V/ ]+ x4 S; r/ v1 V
                std::generate(vec1.begin(), vec1.end(), []() {' O3 Q, n) y3 x7 t% R
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
+ r7 [) a5 J0 L, D! Y1 @8 ]                        });
* E# \% R8 |6 q+ }
2 s7 F0 D1 y3 K/ F1 A5 w                std::generate(vec2.begin(), vec2.end(), []() {
; b4 g+ i% R4 @! w7 e% m1 K                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
6 d" ~7 h3 ^7 b2 Y2 z                        });
& h5 m5 B  K# @, ^" O8 p! g' [" ]* Y% }5 A  \/ W3 Q) p$ a  }
                for (size_t jj = 0; jj < vec1.size(); jj++)' J( f% ~: z. k) @
                {4 d6 B! s. l( C6 g4 s; S/ o
                        b1[jj] = vec1[jj];- V5 L& J+ |' H' c: o, I
                }
. x5 U7 P# u8 j6 I4 Y# n
- j1 S4 L  S9 J" z. G# K! G/ Z6 p7 M' H                for (size_t jj = 0; jj < vec2.size(); jj++)7 R* D: Q* L; R3 a
                {2 I4 a6 W* s% N" ?! y: m  L3 w
                        b2[jj] = vec2[jj];/ I/ v' w8 O/ S2 T3 Q. ~$ A/ N
                }% g' C# h3 x2 u% [

% V2 M) G5 Z: y- l                //Method - 1  N=100000 247s  $ p0 _2 I6 }! f3 t
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);  K) X1 r+ X$ j. s9 D
                                * S8 u! }* y5 |! ^8 T
                //Method - 2  N=100000  237s
, d2 }# i2 s7 d7 I. h                /*
8 b) l' C& C: a& e2 }+ a& J5 T                for (int jj = 0; jj < N ; jj++): j( p2 y* |+ `/ C, @. I
                {
2 d- i0 W6 A9 ]$ ~7 z0 L# Y                        fresult += vec1[jj] * vec2[jj];
# J0 m4 q; ?, F. P+ G6 E% t                }' u; x  y, o5 m
                */
  S; w! l. k, A7 u6 R                                2 ?2 T! g& K. A! T0 y- g9 a9 h$ u
                //Method - 3  N=100000 204s
& o. g8 C5 o& t: D+ e. `1 T, q$ s: l                /*
# p" [( O4 S3 e# ~, b/ \                for (int jj = 0; jj < N; jj++)
) `& B5 t' X2 \  t                {8 F4 r0 z  X# M4 ^1 C1 w
                        fresult += b1[jj] * b2[jj];
% k" I2 @: H$ e, \5 ?; g, e6 ?                }* b  T  C2 M2 \- l$ E
                */- ]) W* \3 o' c. W+ O3 D
. e! Z; ?; N& K6 _
                //Method - 4   202s
7 }3 R2 f+ O+ B; H* ]6 u% N( T/ L" x                /*
9 X4 j6 N$ v1 N7 {* l  W9 Y                for (int jj = 0; jj < N; jj++)
% C8 Q( A+ s. R3 d9 X2 u                {4 T) k/ u5 P8 r  D
                        
8 H. h/ m0 l6 m1 \                }0 j2 @8 Z* s8 g/ W* x
                */
+ A8 z' j1 G* U% c! \                //comment out all methods, N=100000  202s                2 ]. m& L/ H7 O' U! q6 e2 N
        }
% N! ^2 J  k, y5 }) U0 a# W, H) P5 o% ~- F
        delete []b1;
: s5 \( u% M. ]: ]        delete []b2;
* m% X( |5 }- |' F% b) _' t( u. l! w

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
1 o1 o# J  Y$ z" a) K+ d$ M, U6 x1 X* u/ [
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?* F; q) n" \" u$ m" v! y9 \8 l

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15( ~3 L$ q$ h5 S
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
# B+ X0 i  ~# a& R: h" a1 k* p6 c: }2 P, d0 C
你第二个试验里面的j在循环里面又重新定义 ...
. M4 s, M% _/ d2 ?4 ^6 _
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL# V* b- \- O( E8 |4 h* g0 @, n

/ ]# N4 y4 q1 Q5 J+ @, ~% b# {不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
5 x) z) Y* B$ r+ G: U( H7 ]内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
9 M" R' [) B; Y% w! w# f. k- `  f: N; Y) Z6 g7 F& k0 F
不和它 ...
) W% v& @3 L- a
2 N5 [0 g2 ]% E, @
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
1 q1 r5 T1 S/ q- ?5 e后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:548 {  J- S  R  D; o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
/ t" D" d5 S+ z/ |+ B" w{# a+ ^9 L3 ?; m2 `5 A  K
        comp temp, xtimesy;
5 D4 M5 i: i) H+ \# Q9 o+ n$ @. J
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。- K: ^- h+ N: F
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
2 f! G3 J) j! y5 p$ C& y, @+ zVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30$ i. J3 G+ o, m$ o
理了理思路,重新做了一个测试。
9 h! x! }& a  |* Z4 P( e4 f  [  b做了两个 vector 和 两个 float *, 都长 1000003 }: R2 I3 z7 X1 G3 J4 S
外循环 6000,里面先做随 ...

9 y, u4 w+ _$ `" w$ e# L, S) @这个时间是从哪里开始算的?8 N# _" F6 _  F! H0 A
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。( E5 v) k- n: F7 R9 Y  `
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
+ H- Z$ X$ N% {这个时间是从哪里开始算的?" O4 a& x; s# x$ N1 C1 R- [
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
4 f/ B, V3 Q" H! H  G
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
3 N0 K# U7 V: H& O- @5 h/ l你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
- d. j" h, {2 e& p" \* b; O$ W) R与此对应用数组(指针)花了2S
& j/ n) H. ~) Q' m2 d4 L* l你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
; [5 a9 w! D9 D; Vvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# Q' z5 z% w/ v- m7 N3 O+ D{
% c% [& w4 J1 B; |        comp temp, xtimesy;

, g  W- ^' N$ h7 U) K; Y) F我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
; k  A) s0 y( ^1 U8 r. l
5 B# d7 J$ m& N) g
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29& Q2 r- Y* c5 n
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
1 j1 x- C8 H5 K( U0 n, I: y/ \/ `, e' }: O$ k% M( Q
...
' v% @* i3 }6 L4 @7 {) ]! s; o
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
+ X8 {9 Z  V& U: v5 f8 C' w" M; h7 U7 B6 G& c* P
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
* J& G. y/ Y! j- u1 r1 }- P: `1 U- d$ O" k
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。& X( }& Z) x! J5 N, s: T+ G2 m
有空时我会试试 SIMD和并行,看看能提高多少。
1 ~0 T( @  ]. @# T1 g过去7、8 年没有正经用C++ 写过东西,没有 sense 了
  q5 S1 l7 ]4 Y3 [5 P" e谢谢大家的讨论,I learded a lot.  红包已发  8 s% |0 E2 n; o( F$ m

1 U5 H0 \! \* b' X- e8 p9 U1 @( U5 h7 D2 B  E
" Q: F6 L3 c' t$ K2 C& p$ }' S

- G( a  H. l. r" E6 d6 @$ J& ~




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