爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?1 _! s; `) I" V. v6 U6 d" O/ L
+ \( l5 ?. h$ J- ^
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。$ f4 h, U5 Z8 R# R9 K
/ P( j2 X, h$ F# G' b
速度优化问题真的很有意思啊。
0 {; W5 t9 [5 `- y: Y" `, y
9 O, h  \3 Q- Y6 d' q欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?1 ^6 e( ^1 J4 v! [
把代码贴上来看看?: v- u2 V% s- o3 D: A. U; Q2 E

+ M1 R) v! }, }1 ?难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ( }+ Z% e- F. O
数值分析 发表于 2022-9-24 23:04
: q& _7 d7 i$ w7 B5 \拉下来?拉多少?' m. b% @3 J! t8 H
把代码贴上来看看?
! ^, W5 B2 _# u! K& N- v) }! x
& G. W$ C* B: ^% x4 s
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 Z9 f7 x0 Z- d4 K
{
( ?& Q0 E, P0 m) A/ u6 ?, B        comp temp, xtimesy;( Q- l$ e6 I6 V' x
        xtimesy.re = 0;; e3 v1 z! u& E/ t
        xtimesy.im = 0;
8 O; z$ g4 W( f& I; H' E        int j0 = lenB - 1;8 I2 M: X. c$ y- |* J
        int    i, j, i1, reali;
) x; h' {$ _" h        if (lenA % 2 == 1)8 Q( f4 B. b) @6 C6 q
                reali = lenA + 1;
1 I* l8 d: ~, u# q# e& p        else, N! X' F, e$ [
                reali = lenA;
/ T5 R/ a, u8 K        reali /= 2;
3 X: g) g6 |( W6 X9 n8 m+ ^
) S! L/ M! B( z- z4 l" h        int nconv = reali + lenB;7 B7 ^5 K( N  F
        //#pragma omp parallel for8 n6 z9 K' ~4 Q% V( d6 {
        for (i = reali; i < nconv; i++). y- P, M- E. @
        {
7 H% H) _+ V  v$ a, F# i                temp.re = 0;6 h" c; t( ]& r
                temp.im = 0;
& w# ?; I. M! L& Y" Y3 E2 X* F                i1 = i;4 N9 {! J4 N9 i1 p
                for (j = j0; j >= 0; j--)
9 ?8 c+ X! a9 u" k, j8 \                {
3 [* d: C/ ]( v                        /* floating date operation */1 A. R& C* q  U2 \! Q7 Q
                }
& z; E! \( `+ @2 [
        }
0 ~0 K" T/ [3 N! r( E1 i( k}( P0 v0 _0 p( l" q/ |

  p$ ?2 t9 P3 |5 q3 Yxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
/ Y# M  _! Y; {3 m( P& w3 g- p% H. d3 |6 A
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
: ^, I: ?' |. D) H+ z  s, B& W% X现在call xcorr 100次,耗时78s.
# V& S7 @1 C! l9 I) q3 a
: N0 e+ l- p0 o- W. A2 y如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. " Y8 L/ f4 u( s' o/ m# O$ A

8 K2 T7 P* c9 z6 }
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:335 V: y3 m/ n3 p# h9 U2 H3 p/ L
Maybe Debug mode?

4 [8 U2 ~( f; U6 i
2 u- t  J8 N- E( U% r2 j8 N不应该,看我上面的回复。. }1 C7 S# C' y. [# R
3 ^! M. g2 h2 A0 m1 `9 A
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
, Y, N. D7 u, F7 [; X
雷达 发表于 2022-9-24 23:54- `0 C. G! J& _; u6 S/ z9 g% c* D! ?$ G
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)+ z  V- m. x4 j* K2 m
{. c3 y4 {  C# n+ m  T
        comp temp, xtimesy;
+ ~# J7 w5 E+ N! E
" k  C! e- `: N1 o. g, D
这个不是这么比的吧。。。
: R3 a1 ~9 j+ @  _2 c/ m- R) I1 r7 }3 H* M4 F- C4 S0 Q( E9 \( R
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。5 }' \. D$ I% ?) |8 I
5 h* I4 E7 Q5 s# ]# D) \, W
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
- D* v+ w; V3 {8 c
数值分析 发表于 2022-9-25 00:20, m8 y3 A! x7 G3 S1 V2 z
这个不是这么比的吧。。。& g( ~( W, _  X% i7 \
6 b2 m6 v0 @6 K7 K+ O' ?0 c+ _* n
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

. O8 l3 k& T. o( a3 }% W+ j; Y7 K! {
有道理。
9 S5 ^- R1 j3 i- m* J所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。4 w' p' _* j8 b- x

, d* i1 c, x  V/ @我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
5 `9 h* g0 X6 z$ Q有道理。
" \  e' s/ z$ v: C0 @% A" q所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

# _- g1 V  \: U/ N; I$ _% R; @( f你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
+ k( `9 I/ @2 r$ A, a/ W' @Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20, s  {8 ?* A' B% N3 M" n2 `; R2 m7 r
这个不是这么比的吧。。。
( W& W; ]! C  A! q% \- k) \# V1 J) `+ ~  D( g1 U/ f2 Z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

% U% A% I4 q9 `, v
+ u/ \" @: V+ t现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
/ d, F" }  `9 h" W/ Z
沉宝 发表于 2022-9-25 01:48
1 |3 f2 E0 V# [; o现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

( Z5 u$ m( I; K$ o$ L5 Y, z) O0 P3 j  B) f' d4 d+ P. n  O' Q# Z- |0 M
是的,兄台说的对。
; D+ c  N9 |7 m3 ?2 f$ _
+ ~  k6 S; u% j其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。+ s! g$ q, z6 ~$ n, C2 a

1 v# @* ]) a4 i% o  @/ i: O" ~雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。4 J: ]0 g% R' Q( d

! g2 x* }9 W, E/ R0 Y* J; V比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
$ e5 U! O/ s/ ]" d0 U9 ^1 \1 v' R3 O( z' `. R
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 9 H: [/ L: n$ g  z
沉宝 发表于 2022-9-25 01:27
+ O7 y. T( e+ A; u你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
2 a) t7 O) b6 X: {: x( @9 `8 {; r7 r) z

+ K5 m  t) a" a4 O又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
% M: O# D3 H4 x, Q1 u7 {: c( S# e2 L5 a+ x6 o% z
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
- C, m" j6 Y& ]% F又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

( [1 F2 ?4 t! v0 J时间差一倍的结果可以接受。( p: U% w* D& E7 J5 Y6 S+ ~
6 i2 x8 }8 L6 ~. q9 ^
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ! F: M' V2 P1 o; {! }
雷达 发表于 2022-9-25 04:47
$ `6 g2 X: r; a5 p* I% I) M又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, w) T/ q2 C& V/ |6 f/ O0 o" l6 G4 G9 D3 V

' x& A# v) A) F; \7 B  w+ W
* c- r: r$ A, C3 S1 g能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 / k3 m8 d! |0 E5 O" ^+ K/ E4 m
数值分析 发表于 2022-9-25 14:582 y, t! g* P/ {0 s0 y1 @. G
能不能把这个也贴上来,看看和上一个有什么不同?

: l% O5 ^1 Z7 M9 C理了理思路,重新做了一个测试。
6 |3 }9 u$ R7 u做了两个 vector 和 两个 float *, 都长 100000
$ d- y& x! O! |; ^% D( `外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
: Z0 C4 L+ d2 y2 }7 @! W6 r# m5 `! T1 J" P; }- a
内循环试了4种方法,
; B) T7 T$ \' s% I/ R+ l  k1. 直接调用 vector inner_product 247s 3 a- y6 u7 T  U  G& U7 f) t) C6 Z
2. vector 循环点乘累加 237s
4 U) z/ \' h3 I( W/ X3. float * 循环点乘累加 204s
" i& w( D% \+ T4 `9 p( d5 P4. 空循环 100000 次 202s
" `: U* O3 E7 s9 G, h; ^4 P( B7 u: U8 R; d+ z  [
不做内循环 200s; p7 B/ ?: l% R# j0 B' p

. ~4 R, h. d# Y) A你昨天说的对,内循环本身占比是很小的,大头在其他处理。
& I3 C: u, a, A' ~! M, n另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。) D) f- a* r! R
4 Q, l, u) X; E7 n
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)7 X+ W; |5 j, F6 S) G& R% H
( H2 h: X8 ?2 s
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)* H' \* n" Y2 }; o# C
7 j% h" s6 Q2 N2 J9 V
        std::vector < float > vec1(N);
0 x& F/ J; g8 J( _# K8 [+ g7 m        std::vector < float > vec2(N);- y9 C2 Y  S+ E' V9 i+ X+ Z  A
        float* b1 = new float[N];
7 ~; {6 b- ?/ ]" s7 j5 R        float* b2 = new float[N];
) o6 G- S- \( A8 {7 S; Z  E$ x& D/ O; T4 |! {
        for (int j = 0; j < 6000; j++)! R4 n* A7 ?3 s5 B% f- P
        {
$ C3 Y, Q( n0 |2 k: g+ D                std::generate(vec1.begin(), vec1.end(), []() {
& L6 A$ d& P7 v9 v. Y                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
* G' z( Q# D- H% n+ z" s0 u3 X% k                        });
0 n; @- l8 M% H  p1 }5 R6 W" G) k3 h
                std::generate(vec2.begin(), vec2.end(), []() {
$ R3 c, d" L9 l! r, E7 l. b. Z# {                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;* e/ W- O; K! z/ V: b5 S
                        });
" n4 X5 n' o8 X- m% N
, H6 S$ G1 L' _, @' A                for (size_t jj = 0; jj < vec1.size(); jj++)
  ]4 S4 _: `; ^$ \  q; ^; ]9 K+ v3 B                {
0 [# O3 q$ ^3 y) I% g+ o                        b1[jj] = vec1[jj];
( V3 w6 E$ v8 I% a7 Q                }
. _5 N2 u' L% u: V! r1 a" R8 c0 T# l$ ?7 i/ q' K; |4 ?
                for (size_t jj = 0; jj < vec2.size(); jj++)
0 R) A1 i3 P  R  Y- H; R3 c3 \- x                {
1 g0 q/ @" _- d$ y$ @. [7 p                        b2[jj] = vec2[jj];7 C% E5 W, u% b6 k% W/ o/ ^6 U
                }) `# G7 k* ~& T& Y& X

* G- Q, \! M! }& b$ I0 R9 s. [                //Method - 1  N=100000 247s  " ?/ g& E, |2 x, q6 C1 d
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
' c" D. e; p- t                                
) z( ^$ m; N7 M! ~                //Method - 2  N=100000  237s
2 M' _3 N' I& c5 O. v                /*
6 v1 s6 S8 W  X( M                for (int jj = 0; jj < N ; jj++). D' d( d- b' S  A* H
                {6 z8 z: a% r; ~, y
                        fresult += vec1[jj] * vec2[jj];* p% N  [2 @8 U
                }
6 ~# g" w0 ]  g) g                */
" ]/ D1 y$ ?' p! b! Z- K0 W                                
$ L& p' `: y( t4 f                //Method - 3  N=100000 204s
4 q: k8 R& d+ H1 @7 W2 T                /*
5 ]  @2 P& g6 J, d: w. F                for (int jj = 0; jj < N; jj++)$ G' R: {1 T7 E# X6 `( u& Y# m
                {
( Q2 `. y3 |3 B) Y8 l+ b                        fresult += b1[jj] * b2[jj];
$ l0 I. D0 \4 V7 @6 a3 X) T# S                }
) k/ Q( |; i: B- L8 p) n; ^7 j+ U                */
6 s6 T! u% D6 O4 Z4 O9 V9 d+ D, m  P1 Q. D( }- w; i  ]
                //Method - 4   202s& [' i/ m5 D0 u2 ]9 b6 w# H
                /*% \2 O, P+ [  D" X; [
                for (int jj = 0; jj < N; jj++)" C2 w# b4 S& ^& w
                {
* Y4 b# O8 l" g7 @( N                        4 ?4 K& r# Y  E: d
                }
* \$ }; x! f* I# K! E                */' E4 v# m( b/ p3 x9 G
                //comment out all methods, N=100000  202s               
6 j; @& M8 P+ a8 l        }
* E2 _% e7 _- j3 g) N
. Z3 a. ?; b$ g! k0 G8 g. p$ a* c: [" Y+ ~        delete []b1;' q4 m" F/ G8 Z0 M: [6 I" J  z+ o& h2 P
        delete []b2;

' _! N" z2 ?% ]. N
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
" L' @( K! b3 W  a$ T" J2 n8 {
2 N( t7 r2 C, K1 d你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
$ ~* s/ h4 {7 g- Z7 s
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
/ m% Q, [/ r  @" l# v瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?2 x0 J, N1 Y  E/ T) @
; V+ P$ d! @! k/ @
你第二个试验里面的j在循环里面又重新定义 ...

) U4 N& [6 w& y, @( M& q内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
, t! L; Z5 ^4 f1 ?' M" a/ h" Z( ]& d, @; B
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
! N! \4 }" P1 N3 _! \内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
  T' |5 l: Q4 H1 M3 A$ v
5 m% o& N! p6 c$ l4 C不和它 ...
/ O  V& a. G  W) W" m7 ]6 R& V* {# u
) a/ c/ n# C' M
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
" Q! d2 w& ?, }3 i" |后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
' |3 j! I# ~! Fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ `6 p  D) `0 b+ k{
6 J$ ]/ s, `% [% H5 ~8 F        comp temp, xtimesy;

/ a# p- z6 D8 ^7 t3 y这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。0 w1 p% B( H) M+ B& X
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
4 |$ Q" l+ c2 W5 T0 y- q- SVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30: R5 s  e1 w2 ^8 W# }  p, [& g3 Q
理了理思路,重新做了一个测试。* x, ]+ N  ~' z1 W# u* @6 W3 P; L+ }; n
做了两个 vector 和 两个 float *, 都长 100000, m0 }: u* c% [# R- k, m
外循环 6000,里面先做随 ...

6 F7 ]8 ~  l6 M9 P- a这个时间是从哪里开始算的?: R) A2 N$ e8 V
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。7 G9 r: p  }5 p6 d5 ]2 a
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39* f' K- W4 {) C! [8 b* ?
这个时间是从哪里开始算的?
( u8 _; |4 [$ _8 ?我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

  v% C0 i) E3 g" r$ Y' C% w我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
* v4 {* k, x% E! x( j你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
/ s9 [* j, h! C& D7 x. |: ~与此对应用数组(指针)花了2S: I% {+ ?: \  c8 y% l; q
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
4 L. s4 x$ W: X  m: I# _4 _: \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 ?! s3 [2 J5 v- @# ]* G. L. Y{8 t& s4 |) |; `' [& Y% I  ?
        comp temp, xtimesy;
- Q  B) S, {6 D4 \
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
% q! y% V+ N5 S' E9 r2 N! S' R; v, ^+ m2 O& c

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:292 Q* w8 q. a3 w
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
4 c" |' `' Z" X. _2 \
2 C5 f1 d  L) I% y+ Z( h ...
4 T: b: E7 u- W; J: n
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
& e# f; q. ^4 E+ V* ]4 M) D. G5 d; K) C
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 " M' e. E1 l1 {, P
; |) a) V. {# `9 R) E0 b: W( g
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。1 K* w+ |  N" K  N1 w' \; q( ^( Q
有空时我会试试 SIMD和并行,看看能提高多少。
# R0 R' a  p! a+ C6 N+ N过去7、8 年没有正经用C++ 写过东西,没有 sense 了 * u* O3 Z3 ]8 S7 q7 K5 C) J
谢谢大家的讨论,I learded a lot.  红包已发  ; L+ m8 u( ?) ?9 F2 l

4 ]) Q7 Y# h; _' _! C) f) l: _* _. t

6 C$ |- s. Z: ]; T$ K
3 H- ^2 X! x2 W9 j5 A




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