爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
. Q6 W2 u/ h" l, I* X
. A  E+ w, A  s* O' L" }, q自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。! B# i# Y0 H$ y' D; g
: f) f5 O, P4 J( E
速度优化问题真的很有意思啊。
* I; Q( i4 B7 @. Q" ?9 P8 A- D7 P% o! N& s) g. [/ p
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?# N' K4 X) I  R; ?: q( r
把代码贴上来看看?3 i: T: b8 M- k; `! I( O

# `( X9 V  l8 e难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ( M& X! T8 V8 r, L7 m* Z& w0 H
数值分析 发表于 2022-9-24 23:04
8 b, ?2 M* w2 P( `拉下来?拉多少?
8 x+ F# {9 C% Z0 V0 J把代码贴上来看看?
  C/ z7 _4 J8 C" Q3 I4 e
. Q- H/ ]7 P" I0 |
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 P, m/ f1 ^8 c) `4 v{. C$ G1 b) m. X8 O6 y
        comp temp, xtimesy;. p0 ?- n( s8 R
        xtimesy.re = 0;! q4 z; t+ N$ Y
        xtimesy.im = 0;
. v. \# Y$ V# M3 g+ C/ P        int j0 = lenB - 1;/ Q  D9 P) G, y" S+ y. h4 V
        int    i, j, i1, reali;& r5 |4 P5 U/ B, p
        if (lenA % 2 == 1)/ B- _/ O/ E; o& b2 o
                reali = lenA + 1;
$ d! ?+ k% u/ M' x! C3 E        else7 d0 V* U0 D/ A6 y' |% F6 d
                reali = lenA;1 C- K$ `0 y. M5 U+ U
        reali /= 2;0 a, O* w8 G+ j1 A
0 S/ ^. k# \1 ?' T
        int nconv = reali + lenB;
. L( Z# ^: S. @/ P; T, D        //#pragma omp parallel for
# D$ w, E+ V; ]: L        for (i = reali; i < nconv; i++)
$ x3 F6 k, ^( T        {
4 K! Z4 U! V- z4 K1 t' K- {% _8 o                temp.re = 0;
( T, d3 ]# C7 K7 d                temp.im = 0;
% y$ x0 M& O3 I" X' ~                i1 = i;7 b7 a% _" W- W9 v9 p5 u
                for (j = j0; j >= 0; j--)6 z$ ?1 {; G0 B( V. j
                {# N0 U2 j1 b! [, V3 ~
                        /* floating date operation */6 g: c+ w2 D$ {4 X% j% R1 d. f
                }

! d7 Q; i7 F8 k        }
$ d2 J& e4 z; @4 ^" @  x8 a7 X}
. ?5 c6 c: |2 |8 k* o8 k7 C$ u( \5 \% T  _; J/ r3 [" f. [
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
( J2 J; `3 s. k: M. B5 L* q/ {) T+ _1 x# Q; |2 v
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
9 g2 P1 h5 y% j$ Z1 P7 L- L现在call xcorr 100次,耗时78s.
" x& {7 X6 x4 y9 n& L7 B7 J1 R; x
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.   r) Q! E! u/ F- x3 u% M

' x- Y8 b+ H2 q3 S2 ~. K
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
+ n0 y3 _9 w4 XMaybe Debug mode?

5 F$ x1 q4 `' K. y' S
5 Y/ Y, f8 m0 @不应该,看我上面的回复。
3 \/ [1 O' e0 P6 A9 a! @; R! \& }  u2 i. M# _
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
: r2 F! Q9 X  l& A! W/ r
雷达 发表于 2022-9-24 23:54
' q, {3 g# G0 L4 v' tvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# ^5 R7 |. g: g1 n2 s8 j# G{- L* h" g8 c6 x! u2 G8 |. {/ k
        comp temp, xtimesy;
% d% t! d0 B- E9 _
6 `+ h  ^2 _: G. Q0 L' M
这个不是这么比的吧。。。0 u: |0 @" w- C
# w, q9 p8 W; Q* P
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
% c! K; z, y% M! V! R
# l* \' K$ c' J而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 1 y1 X3 l! k- W* H. e
数值分析 发表于 2022-9-25 00:201 i/ L' q/ C( _/ ^
这个不是这么比的吧。。。
+ K  x& M: D0 H
; h( c. r( o/ G/ s- Q- D( W+ _7 l您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 I" Q3 y+ A. i  x7 E
( [8 f4 D' d3 x
有道理。; z4 W8 k" ^  w% i4 `% B) q
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。, a/ v6 N4 [8 c! ~8 ^

, l6 g  j& Z8 N. L我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
7 }( i) E% M9 j8 b有道理。6 Y" p) Q8 q5 p0 u, d8 z. a) x
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
: Y0 h8 \- G5 O: V% E3 P
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
1 I* X# x7 n5 V+ _0 ]Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
$ V( Y8 M+ K* t$ _* h" Z! [, s3 o7 w这个不是这么比的吧。。。
* s; j& e/ v# d* {- Q& f2 p# c2 d  M% z
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

8 U% |1 K0 I! }2 z9 @# G) o6 C  G
5 i2 R; }# \$ |7 l: |) _: R现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 3 T& U: d7 {5 `) O
沉宝 发表于 2022-9-25 01:48* ]+ B& ~. o8 ^) P' k- i6 N
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

% ~) P  B1 n; |9 c% ^  Q$ M. A$ E. q" C7 v, \6 ?
是的,兄台说的对。
( \, W5 f: s3 t( c) C3 {0 i4 p$ |+ o0 D+ \( [2 w% Y4 }1 x
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。. Y( B( b# M  |# _  e, D* c8 U; h4 d
1 c8 ^+ N  N9 j6 k9 x
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。' r1 a. L1 |4 A

! v" c+ S+ }1 h0 x, @, ?% ?0 G比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。" ~& n3 q1 p: U

8 p/ d! ]$ f) u- s当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 2 }$ q' K2 s# f9 i/ V
沉宝 发表于 2022-9-25 01:27
, P/ g3 C0 c7 x4 H你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
( Z# B8 P, ?: n0 [
+ O5 c. x' h. u6 E! s8 {& J* k( Y6 J
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
, |! u8 c7 u# u! J4 o0 Q. s
- \; Y- ]# m# I, x' t6 j我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
0 ]% I$ E+ y) f. Z( c4 s# ^/ v2 L又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

% l$ K: n4 J, \6 [时间差一倍的结果可以接受。0 {7 S3 U- l* n7 p+ ~8 O/ v/ u
2 t' q4 h  V) E$ p# \; e& q) o
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 & ]+ I$ J  i  c+ u% w( G
雷达 发表于 2022-9-25 04:474 f; ~7 C) J5 o8 N& ~
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
' K" n* f9 W- s- B
' T. d. u/ T: c; M3 ]9 v

' I8 x7 f/ V7 p5 M$ V/ Y% I7 O; Z# B. D& q8 j& }
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 7 T& g5 u# }4 U1 T# K+ W  Z
数值分析 发表于 2022-9-25 14:58" P$ }' g4 `1 ?
能不能把这个也贴上来,看看和上一个有什么不同?
/ \) k3 X* I% M7 }8 T
理了理思路,重新做了一个测试。
; ~0 M4 _2 ^: v( b: [; @7 ]9 b1 \( g做了两个 vector 和 两个 float *, 都长 100000  p) C8 v7 X- z* o" E8 L! J2 G' W
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
. n7 J/ Y; a5 p- w7 H# F" P1 H" |7 ]. D1 w3 y$ M# j. O% a
内循环试了4种方法," E, g& h! E9 ~
1. 直接调用 vector inner_product 247s : b1 M4 N' T, h1 I* v: g) e  k
2. vector 循环点乘累加 237s
$ j/ n* e( j! ^* T7 M3. float * 循环点乘累加 204s
! N( _: y: u# Y9 d- p6 ]9 G. K% R4. 空循环 100000 次 202s
  e0 V$ J$ i! p/ r, P. U9 e4 u) z1 W8 o4 F
不做内循环 200s* c4 y" [, z1 B

0 Z  q. N( d) F, n! U! k你昨天说的对,内循环本身占比是很小的,大头在其他处理。7 f! Z# G, ~. }# |
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。& S# [6 A; l$ T* L' X" ?

. ]! |6 Q- d! N, A. n至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)- o, e- i) j0 b8 }( }  @  e% `

/ @9 L4 }: |% O# h(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
/ U  l3 P2 b4 N0 O  v& i. W7 K4 N) I, a
        std::vector < float > vec1(N);. X$ Q: k. W+ r& U0 G5 s
        std::vector < float > vec2(N);- }* z* ^+ X' d: ?, B$ v
        float* b1 = new float[N];
* T* R+ @3 ]! }7 T" ?        float* b2 = new float[N];
8 L% Y  W# k$ U' k) F  ~# \2 t; d/ P" U9 Z' w' |  e
        for (int j = 0; j < 6000; j++)' `) A! A: [. X5 U: P
        {
. y' d8 Z$ ^+ R! g6 v. g                std::generate(vec1.begin(), vec1.end(), []() {2 m2 t! z' r! N5 P# G3 d: N
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;& l' \/ E  E  `! e0 T; d9 m
                        });
! I1 V/ c) o% `3 X3 B$ \# U# v# ], W+ r
                std::generate(vec2.begin(), vec2.end(), []() {
5 C( `: w7 E- `/ K! s* j. `                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;3 r: K% v- X* F4 N: l. A# @
                        });3 C% I+ e& w1 u: N" x$ V* P9 A

3 l% G) \* L; ^$ @* B% ~* c" e                for (size_t jj = 0; jj < vec1.size(); jj++)
* P: h2 [: H: t1 v* k                {
" I! T& o; R( ~2 i                        b1[jj] = vec1[jj];
+ ^: ~$ i$ ], ^0 q, T                }
, f" k3 y$ O6 [4 E( q+ `0 V0 [# I8 [/ b% P
                for (size_t jj = 0; jj < vec2.size(); jj++)0 ^4 M1 S+ P3 M5 l0 e" u
                {
& ~. r, y2 n- R7 B9 z9 y& N                        b2[jj] = vec2[jj];4 B6 N( \, b  B6 K3 p6 T* g
                }
" L# S2 h+ U! F6 n7 a/ }2 B6 v1 H3 Q# n. z+ n  |4 n3 I, n
                //Method - 1  N=100000 247s  : i" z& x, k; w
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
2 T- R' F& B. D3 [                                , ^% E$ g& c0 ^; i% F! I* Y
                //Method - 2  N=100000  237s
9 b+ z& m. }  u- B" T2 @6 f                /*, O: ~' T/ a$ m2 F+ g) }
                for (int jj = 0; jj < N ; jj++)$ A) H* j! E/ j
                {' N5 h: [' ]1 N& J0 S: d; i  s
                        fresult += vec1[jj] * vec2[jj];
1 a0 C8 ~: [% W- N, G                }1 U9 m9 r4 r" h/ `0 ^( |: F
                *// G" ?% e& a; e4 z8 @; {: \7 ^
                                
# \/ c5 R) {5 M7 W4 D; ]. {                //Method - 3  N=100000 204s+ x8 P" H' s% b7 K
                /*. K% D3 g" k0 f7 k2 d8 E
                for (int jj = 0; jj < N; jj++)) W% A- u1 |4 c+ `  Q
                {  E8 N' {5 {" @- R
                        fresult += b1[jj] * b2[jj];
" p3 b$ e2 L% _" n                }& o# b- T9 }% r# y
                */6 Z/ J  n+ d6 a8 n

. {2 F7 R' r( p                //Method - 4   202s% m/ e% U6 W1 j/ F* _
                /*/ \" R% \8 o: Y4 b! m! {
                for (int jj = 0; jj < N; jj++)2 d8 h7 G8 _: ]/ b! w$ a5 G
                {
; D5 F, o4 [* e- B- \                        
- V7 I# E7 ]9 N. [                }
8 M, l; ]4 T. d; |8 [                */
8 w/ ?2 Y( r! Y! W                //comment out all methods, N=100000  202s                ' H' t8 F5 Z; B4 ?/ G  |
        }
: a+ K8 h8 J5 D: @& W4 e! [& d! d; O4 j7 d
* y- ?7 i6 ?% M" _, J; `5 R        delete []b1;4 H, V2 L- A9 h$ B8 m& t" ^1 V
        delete []b2;
9 G- [9 \9 b( Z1 _% t% `) R* ~

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
( s6 J& A9 {+ I( K) L! m
' C7 v' T0 p2 h/ x6 i你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
' X' O" X- K5 H2 D/ c8 M" X, C* _
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
/ ~2 ]( y0 P0 t9 d; [- D瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
3 l3 E, H/ D. i9 V6 a; v4 i
8 A  c# H5 v( I$ K' ~9 D, Y7 H你第二个试验里面的j在循环里面又重新定义 ...
& G( F& ]0 h* `: f4 [3 X4 W
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL! H/ L* @/ `1 X( D8 b- k
* k% t9 b4 z8 g- F
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
$ p$ m7 Q+ x* v内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
9 b0 D+ {3 {- h' g, {7 o: @, {, Z- f3 [$ j$ i' _! P
不和它 ...
- k: R( }; L, S( r% R' E
/ `$ n1 z- @4 v
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。3 z4 s! C8 t2 }
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
: x2 V$ u4 e4 L) l4 O# A6 ~3 Gvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
7 w0 O. V. h$ J5 X' z$ F{; i4 |9 D6 [# \* C
        comp temp, xtimesy;
: H* m- E: F0 t8 r6 T% h
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。9 q5 L: L1 q3 c9 L) l
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?, z7 K/ A# E' L/ w/ E* }6 j7 s7 k
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:305 v9 U4 ~6 F7 i) @( S/ ]7 K# ^% R8 m
理了理思路,重新做了一个测试。& {. F8 F6 B9 q
做了两个 vector 和 两个 float *, 都长 100000
; K" ^0 p( E/ o3 A' l7 V外循环 6000,里面先做随 ...

. L. _3 q  S+ a- d3 O: ~+ ?& I8 l这个时间是从哪里开始算的?7 q2 `% V5 H! a% g8 p9 d$ p4 g- K
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。3 N6 ^, n* S( t" c. y8 N
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:396 x1 }5 J2 O1 M" Q
这个时间是从哪里开始算的?. d; l! v+ b( I, X" v
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
2 a  k; v. Y/ U8 Z* p
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
$ B. J4 ?: D0 L; T& K% c你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。, s! N6 C% Z$ [6 x# o+ ]# d9 }
与此对应用数组(指针)花了2S" G1 P( U8 Z2 R  Q
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54% [" T1 q& h3 k+ T3 l8 U! b
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
% [6 z4 d2 t( P' @7 H& w{, J8 O0 W% U5 U
        comp temp, xtimesy;
$ [' F/ i7 o# l# @4 P
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗- m) i- G- V/ b6 z% N

) U, V. F  F4 L, {
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:298 ~; J' V- q5 n
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
- p5 M  G- g1 P0 X6 k# w! N4 H+ w2 o% r4 f) ]" t
...

$ m5 d" g/ j& C& n: b$ l3 ]你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
' l1 I1 @" p5 }1 z; U' l7 b0 x5 f3 }6 s+ q
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 / I' a. B; k; D* [% t# D

  ]3 {( A  M( [; h8 f. y是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。, f' J9 t8 f- i9 Q8 C
有空时我会试试 SIMD和并行,看看能提高多少。, g0 A2 r6 O5 t' \4 e( [( U7 M3 J
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
$ `  ~- m& M7 K" `谢谢大家的讨论,I learded a lot.  红包已发  
  U, d: l" u3 G9 B: I% }) `
8 }1 Q' B- T! y/ A& I! P! ]: I% h! N) X0 x
1 u$ |- i/ N- k

0 v( _7 _  K/ j$ h- @- y2 B; x




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