爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
" R4 C0 ?7 |: d  q/ g3 |# F# h$ N1 G7 B1 s
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
8 |+ e  W# F) ?" ~( G8 I/ c' i9 \. V* T% H9 Q8 a4 j
速度优化问题真的很有意思啊。
" ?$ E- q" |4 ]9 B6 u, }% q% J+ F* y% P' N8 f* q  k+ C" p
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?. @# p) W" h+ w# h/ Y. n
把代码贴上来看看?
# v6 B% v1 L- [* a$ W9 n
, A5 _  O. j2 T/ T+ m% i. R! W难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
% K! M1 ?* m0 a" M# V9 x2 @& D, U
数值分析 发表于 2022-9-24 23:04. k. U& |" d3 A8 _# [# L
拉下来?拉多少?
! q7 p# m' @' N5 p0 ]把代码贴上来看看?
/ h/ E* I- I0 w/ r$ V! @
) k1 e3 K) R6 @. m8 t
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)3 b8 o' o/ _# X
{# a, z: d+ ]' n  @9 D/ t2 Y! K
        comp temp, xtimesy;
' s* b$ f9 \3 v- [. a7 u4 E* o/ t        xtimesy.re = 0;
8 q: ^( F! q4 ~        xtimesy.im = 0;
9 H$ t" O, J6 Q6 B) v        int j0 = lenB - 1;4 R" o1 F3 U$ D% T4 P% c; c
        int    i, j, i1, reali;
% U% j* p! s1 `" @        if (lenA % 2 == 1). Z7 m9 q4 O3 p
                reali = lenA + 1;
* k# A+ |" W/ r& _8 s4 E( O        else
( T! K. ?' z2 s8 \2 Z/ S                reali = lenA;8 I* X! n, l; P) S0 B; `: Q
        reali /= 2;
/ @; H1 n# `, J. l& ~8 f5 D. y- _+ D' L4 j
        int nconv = reali + lenB;
7 @2 q+ E+ }5 |. q# J3 j        //#pragma omp parallel for% a$ h& z3 U1 a
        for (i = reali; i < nconv; i++)
* d  N6 o7 S' x- Z+ A        {7 Q3 o$ J9 r, A) z# Z& ?
                temp.re = 0;* `7 Y4 c6 S+ v1 i) \
                temp.im = 0;5 n7 U. I5 U- r5 ^) M1 J" H! s) q
                i1 = i;* `; h* \" l* R/ |# g  m
                for (j = j0; j >= 0; j--)
2 Q6 t0 p+ D% G% t7 H                {
2 w) _- ?1 b! r+ N3 l                        /* floating date operation */
: K' b1 G) Y- q3 M, I' v# Y, z                }
! H! O: \8 @, B6 y( }: q$ y
        }9 f4 ]1 j& e2 \) |) }) b; A
}
$ A% j- r" t# K) @6 ~- _" m6 }4 K1 A- Q; c  p" P# Q) ~5 Y! q
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
7 l- n/ L% Y) _  p8 ^9 T, O0 N1 c; W
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。! Q" r/ x# U3 R" |+ P# u
现在call xcorr 100次,耗时78s.
2 j/ ^- b6 D8 F1 F
- j+ _& f/ ?1 H! o" k如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. , v1 E" v: u2 Z7 h1 E3 n$ u* _+ K
; ?- G3 p- q# V7 m0 ^

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
/ y9 n# J( e$ L% g( D, J8 _1 f) cMaybe Debug mode?
; [3 S3 s/ x4 t- Z# b9 e

- ?" c! j& S0 }) |不应该,看我上面的回复。1 s& M$ V2 R# P1 k  k+ A1 G. {& s

  G0 l2 t$ h/ x) B我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
# _! n: ]; [" n5 }
雷达 发表于 2022-9-24 23:54: b  a; \7 \8 L5 R% W
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)  L' F5 |  w* y  J/ k  k
{
5 |4 r$ m; J# b7 |1 _& C) L        comp temp, xtimesy;

( {; b! G$ _+ }4 x% m" `' n! b! O) U1 Y2 N% |
这个不是这么比的吧。。。2 y$ B5 N/ q$ G  A& A
6 _& H$ ^) @2 |( B4 p! q& _
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
& [% u1 L% \8 e5 F$ E; H- |1 w: ]9 ]
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 ' F# c1 A' ?8 ~. K$ P: x
数值分析 发表于 2022-9-25 00:20% x4 }- ?: ^) u$ n) |( U4 O' M
这个不是这么比的吧。。。) s4 G3 W0 C1 u7 T# k' O3 r
  m; |% A; g& \1 Q3 b: n  w
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

" s$ ~. Z6 I6 E& H
1 ]( E0 |  x5 G( b+ f. I; M有道理。& p/ l/ n, T. C( N# s/ X: A/ `
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
7 U8 K/ R5 D, Q) T& T. b  [& f
/ v+ |" u7 s% E) @$ G& ~我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:463 M+ K. A8 v+ f  b
有道理。
2 w' t( `- B, ~3 c) Z3 D所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
6 ]. `3 P1 ^! j7 w& I
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
: r5 |) G/ r3 qWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:207 j* ]- g7 ]( g% G0 r% d6 k) ~6 [
这个不是这么比的吧。。。
& A' E$ r  j3 h# [9 \& V" p5 K$ x. g" _  ~0 s" w
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
+ Y# {9 Y, W8 x, d* ]$ \

0 ]' }6 G. w+ L4 @现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 : F: ~. @( T0 a: g( Y
沉宝 发表于 2022-9-25 01:48
; f, K/ A* _( Y& e3 ]现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

9 R* L  @( q& }8 X' Y! d- R. o2 l
* @! r5 O6 A1 E; y( d' a6 \. V+ \是的,兄台说的对。* }; S8 j( Q0 Z$ p" Y: @

9 W( W3 U( K# Z( W7 K7 m其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。0 B% y! G) I6 O; M+ p
9 q8 F4 @% p4 ]. y5 M+ R/ h1 K
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。2 K* Q; c* @. q6 J, s# Y) Z
( h* G2 F8 U$ c
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。) H9 s$ N# ~! S9 k% S. R6 b

/ u& a, b" C$ b& }: a当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
' I( }. u5 I0 F# g5 K
沉宝 发表于 2022-9-25 01:27
, i$ d5 C* a. F# ^- p6 k你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
% D  N- z$ ]& ?+ D
; R( [* T8 T4 K! w5 y
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。  X6 l$ n0 ]8 }' ?  e8 y
" f% n- T$ x% R% x, O1 D+ W
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:473 U3 \' F* E5 ]0 A7 p1 B! i
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
9 p6 x# n5 \7 d* V
时间差一倍的结果可以接受。
/ x$ J9 E0 U$ q2 A4 w) X3 R  \4 H
- z' X1 @) z( o4 Z: z$ o* }你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
+ A! J1 `( V$ q
雷达 发表于 2022-9-25 04:47
* `% t4 M, J& E又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
3 q, A+ f2 R& r: g  }# Q
$ A  J5 D. D% x! P

+ o% T$ C5 M7 T! D8 A0 x: k8 @6 ?+ @1 U* b0 H( @) h$ ?
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
! L3 d2 f4 ^/ J, X; |$ O
数值分析 发表于 2022-9-25 14:58, r- }, f8 [# ^4 I1 U
能不能把这个也贴上来,看看和上一个有什么不同?

& u7 h9 K# D4 W7 S3 t/ G/ q: v理了理思路,重新做了一个测试。0 C0 q9 t8 M7 Q& H6 H- y9 F
做了两个 vector 和 两个 float *, 都长 100000; N! |* f" \+ w& [, ?& h
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
& K( d, g" ~, I; O/ q) V6 e* p8 r) Y2 {
内循环试了4种方法,
( a5 m* S: a/ X+ U1. 直接调用 vector inner_product 247s
" N2 U/ ]4 d( D2. vector 循环点乘累加 237s
5 S! u% e! ]5 \: \2 ?3. float * 循环点乘累加 204s
1 }9 R. x9 R. X5 E, ?+ b; D5 x4. 空循环 100000 次 202s
9 e* ^2 Q( h+ l9 X! w6 B! H! u% B/ [) A. F# E
不做内循环 200s; A" y1 a4 P6 |7 Q6 m

/ t! B& j. f# O8 H' X你昨天说的对,内循环本身占比是很小的,大头在其他处理。, Y, n7 B- d- u& ], g
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
( V! q) P2 T& h3 P" E/ f# G  ?9 O' |0 n4 u7 f9 e
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
$ h; Q7 J+ t4 P3 {2 M2 F$ Z" ]$ h. L% ]0 I
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL). G/ t, G; q* k# l: w
% d$ }5 `/ v- V) K% k
        std::vector < float > vec1(N);. N/ a' [: h0 V+ a
        std::vector < float > vec2(N);
* t$ C5 P( k9 l3 Q; w' P        float* b1 = new float[N];! [  S8 f/ q$ ]1 ~
        float* b2 = new float[N];
! N9 {* G# m. }' }, p% b+ m* a2 {, h3 C$ u4 E
        for (int j = 0; j < 6000; j++)
6 g2 _: S; J* c* I0 I7 i        {; d) ~* V: x# _1 N/ A
                std::generate(vec1.begin(), vec1.end(), []() {2 y  t' U9 z# E5 j, ]  f
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
! w$ _% I4 W( t9 ~                        });/ [1 W- c. h: T# y

2 s0 M1 }$ N, J0 y                std::generate(vec2.begin(), vec2.end(), []() {: L; c% x" q' z7 x
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
" g7 M- _0 h4 o, U# y5 i9 A                        });5 K* d5 m1 o4 D* ?) d- l! f0 y/ i6 Z- t
% m: J, u$ N8 N( a5 W7 a" U" [
                for (size_t jj = 0; jj < vec1.size(); jj++)
3 F' f( O! H1 I, Z$ A                {
* c. ?5 u0 C( f                        b1[jj] = vec1[jj];
% C+ o7 \; V8 B                }4 r! ]* b% M3 {" I. y: ]$ O4 _- W
9 f4 n6 i0 v+ @6 t: C! [/ p
                for (size_t jj = 0; jj < vec2.size(); jj++)
: T  K2 K" l7 ~+ t2 Z/ ]) |9 o                {1 c8 z. c, p" A) B
                        b2[jj] = vec2[jj];
& h' R- f, I2 b- R2 ]& Z                }
/ T) Y4 d; ~' B9 h' X* `, Y* e' T( k& o7 |8 q( |2 {- ?2 Z
                //Method - 1  N=100000 247s  9 b( L# l$ K0 O. Y( @$ t
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
& ]6 n+ w  I- m! W% O                                : w; r% E1 t1 j3 d2 x! O
                //Method - 2  N=100000  237s
1 C5 j- d' _' ^7 S+ A                /*2 b2 Q5 h' |! O$ [* J* K8 D
                for (int jj = 0; jj < N ; jj++)
1 T3 h' H' t4 I5 R                {* n0 c: a8 Y' `7 @; m
                        fresult += vec1[jj] * vec2[jj];, y+ v7 B+ D! i9 y4 m
                }
0 v2 w! l, f% ?$ N; T* N8 W* \                */( @  U( K% O( h
                                  @: t; w: e+ h# w. A
                //Method - 3  N=100000 204s
; G$ E! l  Q# m# T$ K) E0 |                /*
6 l  L! ?$ Z" W                for (int jj = 0; jj < N; jj++)! S. R7 R2 P" l; I! K5 v
                {
* j; U% q5 r% d# u; H' n$ D                        fresult += b1[jj] * b2[jj];
) Z5 @: _* U- g1 \2 D% r6 ]5 ^                }
0 j( `# h! ?- g- O1 ?3 a% n                */6 s' i2 W  z4 Q% c/ H8 i/ I
3 E0 r) _; H) l  s4 O* a+ G
                //Method - 4   202s( J0 O2 h) V4 M
                /*
, |! _0 m& a3 ?* B# C                for (int jj = 0; jj < N; jj++)
6 z: s: E5 k$ j                {
: Z) P# _  I( \. F: v* d                        2 C4 l4 Z& T0 q0 H) C: b( [
                }: t* m0 \. z+ u# F, f1 ~! B
                *// n) [5 E9 b- G$ }. K0 _* [
                //comment out all methods, N=100000  202s               
% M7 k# N# D' H) Y        }
* U' C' S! i+ X  e! J" k+ _; z% f4 A6 s( u! F" H6 l* ~
        delete []b1;$ o; C$ l. a, ^8 ]! K
        delete []b2;

/ @* e! t2 }+ f/ ]
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?" E4 k3 k2 Y( R* ?. T

7 I, v, E& s1 W4 f  C你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?0 b) L4 Q0 W  q+ g  N

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
1 M2 Q7 n! Q! K% E  a: ?9 y瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
" C& x* E- F) D) {0 o7 W
# j9 M, A  y- S  a0 |. u你第二个试验里面的j在循环里面又重新定义 ...
( A) ~4 ?# c6 k) ]; M/ M
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
8 K0 V6 o5 m8 f7 P3 c0 f% {% v
5 M. O% d9 E( U5 Z5 w( H0 K' J8 t不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16% q  d. z* w( f9 |4 l  L
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
! F5 U3 o  ^: Q& k# K" |' H2 k+ G) E3 W
不和它 ...
  C. F( \9 u* W$ o8 ~6 \5 [
* x' e8 M( O' `5 S, v
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
8 L* L- B( ~$ O) `后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54' u- E  H  Y& T
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
; d! l9 g) R  [" P1 ]! _{% G2 k' ^9 z- g
        comp temp, xtimesy;

. r/ M" z/ t1 y$ q6 f% B8 r& \' e$ E这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。( I) |6 C; K1 s8 l1 S
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
! h4 S  P7 }7 B" v1 k8 UVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:304 V. `( {* P) Z- I2 q! V0 A- {+ ?
理了理思路,重新做了一个测试。6 @  Z4 R; j  k. {4 W
做了两个 vector 和 两个 float *, 都长 100000
5 @# W: x1 f$ J. ]6 A  C% @外循环 6000,里面先做随 ...
( k, h- R9 \4 k+ [7 r# F1 {# v' {/ a
这个时间是从哪里开始算的?3 M: Q( r6 q4 J. E
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。7 G" f* L, _; c1 ^
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
4 {7 U5 b8 M) k8 q这个时间是从哪里开始算的?0 K) ^9 b- M7 U
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
! f- D- l: v& c4 w: ]3 `: V" }) q
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
/ j0 k# ]0 a( `2 m你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
, G3 i. a& z% \) G与此对应用数组(指针)花了2S! F' e8 [4 l9 Y
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:547 _4 Z' i1 J* b& T
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
8 c; C- ^, ^0 o# U  d2 ]8 `( u2 a{3 n: [* A* \  m- @  @/ U+ l
        comp temp, xtimesy;
2 f2 Q# q) U9 K* r2 B/ T2 x* c7 G1 T
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗/ t; J4 s  G: q; P# v

9 J: m+ a4 e! A: y
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29# t) K2 P$ G3 }6 ^
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
; l! D4 D4 P5 `1 y7 i/ E: Y6 M
...
; L' u( i4 ^) D0 k! I$ m
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。1 m3 }, ]5 N. p5 q* q

0 ]3 b6 M1 @' `$ {9 b/ r) N雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
% c  L( l$ F" e' o1 R# y* ]
; ]4 w5 ~. \% v& q& v  i是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。# @: Z: Q9 ^: m4 i. Q% |
有空时我会试试 SIMD和并行,看看能提高多少。
& s. m; m  b8 l& b& O过去7、8 年没有正经用C++ 写过东西,没有 sense 了
: `! X8 B* R5 A9 Y5 J) V谢谢大家的讨论,I learded a lot.  红包已发  
" p+ u' Q! R+ _4 m2 T, G. M$ p* s; ~: k" r1 C

" b# L9 V( [# S' Q+ E6 _/ {) `& m+ D& ?) h+ Q; H9 f

" ~) M4 a5 ~) X+ d$ K/ T




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