爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
9 B4 O6 W  n7 M2 T$ s- g9 \
, |8 ~. n5 {+ c4 d% I自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
0 t- M1 ^+ [6 D$ Q
: x! a, Q  x% K% x4 t- W速度优化问题真的很有意思啊。9 g+ Z' R( l+ H' V
- R2 g6 K# w# V8 _
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?4 Q* ~* b0 ~8 e. F
把代码贴上来看看?
# m+ A. f; B& o. ^
6 A% ?  m$ H% W难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
: D9 M9 L& L4 c0 |$ i
数值分析 发表于 2022-9-24 23:04
5 f3 G; x. y, U5 \) }  d  r% \拉下来?拉多少?: g. c) Y# Q& ]
把代码贴上来看看?

0 X0 |) g5 W: K: Y* M$ g
" T4 k* m: |' J' r0 L) p) xvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)+ x3 G! W, A6 G9 J+ @, a
{' T/ u7 X7 j/ d4 v/ P3 f( z
        comp temp, xtimesy;
( K3 f& C0 @' [7 ~        xtimesy.re = 0;! j) i9 E" O0 f7 ~5 t
        xtimesy.im = 0;
, o1 S! \' ?' a5 m: r        int j0 = lenB - 1;$ b. A) s, K7 a2 _# V' v
        int    i, j, i1, reali;. B9 u( h) s' n2 o: t
        if (lenA % 2 == 1)2 K# p$ D7 x$ w5 f
                reali = lenA + 1;( {- K2 `! L6 {. P
        else( N! S% H, r4 e. v
                reali = lenA;9 w& \8 g2 U, `& K! X9 i
        reali /= 2;$ J4 N$ |, t" }

! {# `4 h! b! r# f        int nconv = reali + lenB;
* k- }' B4 P" u        //#pragma omp parallel for8 `5 i" d# U5 h& y& K8 S
        for (i = reali; i < nconv; i++)
5 s  G5 m6 _5 m5 ~. e9 Q4 k0 p% l        {. i* K: ?. W; F/ `, F0 @
                temp.re = 0;0 z6 b1 m9 o9 K1 j/ z6 p$ D
                temp.im = 0;+ D$ y) F7 v# d+ y# |# f* \
                i1 = i;* m$ _' _6 b. z/ u; d
                for (j = j0; j >= 0; j--)
6 t; `5 b" Y. H+ e! C7 U                {* T/ X8 W! ]+ _# K% N$ A! f
                        /* floating date operation */' c' c$ m7 V( [, g
                }

4 B  q' K, Y6 S        }; h1 @. H: e3 c0 _
}
* b" f8 D2 y, m) ?9 |1 V0 O5 w
, _( S) s7 ?/ y7 e" `# bxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
, D$ F  q% G9 D" z7 s) K/ p9 \. s" p- X$ R3 s& K6 D* H4 R7 M  \
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。8 C& H2 p) K: A
现在call xcorr 100次,耗时78s.
3 w+ C- |& l& Y! H% M4 G" J# d" g: C, H$ Q
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 0 N: H) x  d6 \- N
, J/ d0 q( ]# v) }6 D/ A

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
  B, n7 g& s* q$ E& z& F  AMaybe Debug mode?

' s( z+ y/ h1 V  z: a4 q
  l. `$ [% [3 z不应该,看我上面的回复。- L) g  ^! F' o

8 }6 Q, ~) f% V4 w: W$ V" |我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 5 X* F6 T  }9 P- q5 v  C6 m
雷达 发表于 2022-9-24 23:54
/ y8 ?1 P+ ]- uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) G% o, P$ u- k4 D
{
4 {9 O3 P1 y! ~' \+ {        comp temp, xtimesy;

, J* w, ^5 X& ~; Y1 s/ Q6 @' q  M. q; |- }' _, U6 w2 v8 ^
这个不是这么比的吧。。。
# w! g. a0 k: |
' K  l. y. S0 C# [您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。1 |: m; t3 T0 v8 H9 y/ a

. Y; D2 p9 O9 W4 j4 t8 z" d) Y而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
, {  f5 |+ A. L0 B  R
数值分析 发表于 2022-9-25 00:20
5 R9 \3 |& J0 }$ ^3 w  }0 m- @# l* J- p+ k5 v这个不是这么比的吧。。。
1 v$ f9 M! O; j5 w4 D: b7 Q
9 H& @3 b8 ?/ g3 N您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

8 |* x5 L$ V& c
/ v. s2 _8 V' N+ s# y有道理。0 G+ e7 D8 M" Z, h
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
; B  {' s- e/ a( ?/ d( Y2 i. V, G+ n) N$ I9 p
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46! ~+ ^+ |  @0 m
有道理。( L" C6 X+ B9 B6 X5 i
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

, i# ~1 Q9 ]7 a" L1 `你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多- a6 t1 }$ X2 h/ C
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
$ _) t: l# q, d5 X' m  Q这个不是这么比的吧。。。
9 e+ y/ }( o3 G7 X5 }- O* a: d4 [2 n) i5 I' }( F
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

/ V% R# f7 g  K( I( M# W" {9 i# }
8 ^/ `0 y. X2 g  w+ c现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 ; p& U4 |  E5 z0 [8 e
沉宝 发表于 2022-9-25 01:48; a' K) w; A. p
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
' a  U; S2 W( x" x' m# E
- W. G0 c) r2 t/ X4 d; d1 ]
是的,兄台说的对。' i2 m. r! }2 G

2 i  \9 g5 C: `5 ~7 c& @其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。) L1 L7 O* w" E
' E, |% g" G8 _9 r* f
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
0 L) K2 Q' W0 b& @
1 e5 ^% Z1 {( i' h" }2 x比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
1 R- O/ @2 s; O* v( x+ j5 O3 l: @1 `7 b2 Q# y/ U) o) M/ g% ?
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑   l* \: ?8 Q0 y) j
沉宝 发表于 2022-9-25 01:27
" }, |3 a, h) g  s* S) p你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

* T) \* `: E: ?. @8 a- R5 c6 U4 a5 h, p; M' S  G
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。  @. |# a  y. p/ \8 @- _8 H
+ t9 w# l( x7 Z9 Q) M/ d
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:470 M# {2 f1 w% c1 R
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
, b, G7 ^. b; l+ l( _" z
时间差一倍的结果可以接受。
4 {; I. {4 `3 L9 |! `& S
3 a5 f6 p8 B( p1 B2 e6 |! K你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
' T1 p. }& ]% q  u8 p
雷达 发表于 2022-9-25 04:476 E9 k9 Z: c  r) h
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
' g6 I4 P( z! w3 n0 v( U' J, G

+ a9 H8 D0 ^  U( j$ C# g! W) c  p$ Y& X2 P0 y' G8 V1 i* {
" O4 \& P3 u. ~
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 B0 r8 ^7 T2 s- t
数值分析 发表于 2022-9-25 14:58
9 D; ?$ @5 X3 }& N2 r0 |  X能不能把这个也贴上来,看看和上一个有什么不同?
( M$ ]% T0 F! ^: t: o( k8 C8 W6 c
理了理思路,重新做了一个测试。
0 ?. @, T0 g$ l( o$ V做了两个 vector 和 两个 float *, 都长 100000' p9 r1 w2 U9 D# o4 n/ u
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.+ W; h( N1 O4 O/ Y1 S

7 V  x' g( y- O, {: i内循环试了4种方法,/ g# N2 s  ~- o, n
1. 直接调用 vector inner_product 247s
3 _( o3 ^( D. l/ G2 ]; c2. vector 循环点乘累加 237s9 g9 W! P; i7 o* w  `
3. float * 循环点乘累加 204s
4 \6 e8 B" e; y7 p9 z7 r1 U4. 空循环 100000 次 202s
; `3 a7 _' j( P3 n( g
$ Y3 N7 D- g0 f% j( ~3 c9 U不做内循环 200s
7 j; i/ o2 P/ j# \, f) U1 o! e1 o* h' H
你昨天说的对,内循环本身占比是很小的,大头在其他处理。6 E& I% c$ E4 P# A
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
" E8 i. {9 G& d+ O0 C
3 T3 f$ ~1 b0 X. b" O至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% P6 y7 L* M( V0 M
- @& E% z: n/ R
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)4 N& D5 u# M9 J# j0 l8 a

, l5 M# T: ^. h0 J6 `, ]
        std::vector < float > vec1(N);
/ A' Q6 X. N. Z. ]        std::vector < float > vec2(N);+ K5 E) E+ J$ s* r% ^1 k
        float* b1 = new float[N];
9 _) m1 d+ D* [        float* b2 = new float[N];
! t' C  e0 w* E) ~' @  A) Y+ M) j8 r! ]& [' X  L. {
        for (int j = 0; j < 6000; j++)
9 f" N( y- \+ ^' k        {) M/ _( h7 m- _
                std::generate(vec1.begin(), vec1.end(), []() {
* G; r. Q* P+ f0 T4 H) N                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
$ I! W" l/ l( S3 O/ P7 r! _                        });
* H0 y: `& T% z0 I+ d1 z' n# ~# E2 R8 d
                std::generate(vec2.begin(), vec2.end(), []() {
3 m) y1 q1 @1 }8 M                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
2 [( Y" A* U: [9 x) O1 d                        });% x9 I0 K) }+ |8 u( N& S
  X3 l7 W3 u( k5 f
                for (size_t jj = 0; jj < vec1.size(); jj++), S% E* O- ?5 c4 \( O) q4 D
                {+ o0 \& X% i% ^2 R% ^
                        b1[jj] = vec1[jj];2 w$ e8 @, ~3 Z* K7 t+ ?+ l3 i' m
                }
7 F) Z7 h  z2 g$ ]: U/ X! U' _8 O
                for (size_t jj = 0; jj < vec2.size(); jj++)' i* p. H" f- b
                {
2 Y1 i( o* Z& ]3 ?- k                        b2[jj] = vec2[jj];
5 j3 Z; B3 F4 o/ R' [  k                }
" w7 Z/ A, M) l1 c0 m3 ?- h+ Q$ y
4 D+ T- t' @6 V4 w3 H5 G                //Method - 1  N=100000 247s  
: e& W) E5 l4 f& y) u7 i% }) r                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
" O) v! h! T" D5 y4 I; B                                # C, E: F  A5 D) k
                //Method - 2  N=100000  237s! U; ]5 O& \  V9 W1 t- Q0 {
                /*
  K4 c- u: _! I. O) x+ ]                for (int jj = 0; jj < N ; jj++), I; F# w% H: C% A5 @6 f
                {* r$ O9 l% B: X
                        fresult += vec1[jj] * vec2[jj];* `7 W# o: Q: X6 y
                }! s- A  }- g- u% y. s
                */  a# _) x1 g" P9 U- g" U2 L+ L, v  T
                                
/ F$ T, H5 b0 G1 ?( P+ z6 b                //Method - 3  N=100000 204s
0 F) Z* z, g/ N+ N                /*
* c3 [1 [$ U6 o: g) B" Y1 ~" |                for (int jj = 0; jj < N; jj++)/ s! M2 W7 e( S8 ~. _4 a
                {/ \2 @6 {. i' k& x
                        fresult += b1[jj] * b2[jj];
+ _, D* R# D4 N) |7 A% Q                }" U8 h: E  L! g) i
                */
$ [' H  ?4 K( @0 B% k" j6 o& @# T
                //Method - 4   202s& U  B$ E' b: s9 D( f' q
                /*
( @2 X! o8 s  ?                for (int jj = 0; jj < N; jj++)# J$ Q+ U% G" X% p
                {% \4 \4 e; Z- C/ B3 G$ a
                        " A" y; Q2 R; L4 L
                }
$ ?& {! s% G9 F  p                */- U5 f1 v" [. \  e
                //comment out all methods, N=100000  202s                # S0 J/ J( v' J: |' N6 X5 F
        }6 }: W# p) i' P: u& k: }) u. w. g
" y4 `1 }9 O$ A, e6 W
        delete []b1;( m6 |7 o. D, ]( [
        delete []b2;

* P8 v% d& \% i7 L
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?* A; }; p# a& s4 k1 w* e7 _
8 J9 L) r( P+ K) K4 E+ i. V- z2 z
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?3 a2 q, l3 c. u1 J& B

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:158 ^# y" D, y$ |' ?
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
6 S# f# L: P+ Z, @4 z& [
4 k! `$ K* p' q0 B) ]你第二个试验里面的j在循环里面又重新定义 ...

5 p* m! G6 g- Q$ A内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL, e4 E( t* j6 j4 B/ }: P( q  p
& g: D5 r# J" I& w; Y
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:160 S' M1 ?& }( F  V
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. o" G4 O. _6 w4 c/ [5 y8 f
. Q/ P# g& Z0 ?: R  k6 s; V& V
不和它 ...

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

4 L0 G  K0 P, X. P# S+ L, K1 M我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗  X1 F: g& g' N/ o
! v9 A; t6 X3 a9 K8 d& y

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29" l/ `( a* z( c. w; a8 ?
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
; O. @8 S1 C& ]" Z9 z7 h
2 G7 }9 e' W0 f- s ...
; }' l6 S! {" S3 J
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
' ~) H& M  q2 F& [2 x( ]8 C( x6 {# @; [: X) r8 D  Q
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 $ X8 r7 c( y/ s$ x, I0 ?1 l
5 J3 s' T- C1 V, g" v. b
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。, R& p4 N8 w. W- G5 ]5 Q
有空时我会试试 SIMD和并行,看看能提高多少。
6 n9 @# z5 O- A4 E: }0 h1 Z% t过去7、8 年没有正经用C++ 写过东西,没有 sense 了
- Z1 `9 [! ?2 u! X  }1 _; L6 o- R谢谢大家的讨论,I learded a lot.  红包已发  
! y: d0 |! a7 T6 a  T. o# N2 b) r/ I- Y2 e
+ M2 ]( O9 W$ t( W3 U9 |9 o- {

. a! |( p! v/ {% D9 S& a! U6 N* x
0 L. H: E, W0 D




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