爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?- g+ M" |/ l3 ^/ {( I0 i* N

! o( F' e4 {1 y3 o5 U9 V* m8 A" J自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。4 |3 G, D8 I7 B$ p
4 C, ?2 [5 i% Y+ k' g
速度优化问题真的很有意思啊。
9 `- u" Z+ j  j8 z( ~) x+ I
9 \4 V) K$ {+ p% ^欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?  _; {9 K$ U( q1 o
把代码贴上来看看?$ {9 X1 y2 ?& h& O

9 v) b; [* L0 _难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
/ R0 B' Y  `; u" z8 Q
数值分析 发表于 2022-9-24 23:04
3 g1 M# x, [$ G5 o0 J& M拉下来?拉多少?
) }0 G/ B. |- @% x* O$ ]$ ^把代码贴上来看看?

+ ~2 G# z% O; v. @% _
* P* [: s, O' h# G& T( x2 e' {2 wvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
! ]8 \$ e- O# S& o2 m2 J{
' ^/ Q8 Q2 F( r: r, Y9 S8 d        comp temp, xtimesy;! e& l' ~, _+ r7 r. P
        xtimesy.re = 0;
, E' y2 V' f5 |! j% p! g        xtimesy.im = 0;
! ^- w3 v" n, ~. z& I        int j0 = lenB - 1;
/ y6 I' |& I9 U; g% q# L4 X        int    i, j, i1, reali;
# B- e1 w$ J0 h5 j        if (lenA % 2 == 1)8 W0 N% `+ i2 |: z
                reali = lenA + 1;7 W7 L8 ]+ r9 w
        else
3 O  Q( @' h& S6 n                reali = lenA;
  g8 }* n  _, k/ N2 o* i9 a* s        reali /= 2;
- H* P7 j) G1 \
( b7 `8 W, ]7 T# O" H8 p        int nconv = reali + lenB;5 h& J  N' D9 m% J
        //#pragma omp parallel for/ D; U9 J# Y! W( u
        for (i = reali; i < nconv; i++)
& t* P# l8 x( q2 l( y+ M        {
' T& g8 D7 Q6 m2 q                temp.re = 0;- Z, k$ o0 j4 W( ~2 K$ v
                temp.im = 0;
' C/ k* P' ^0 D7 v7 f' v4 r                i1 = i;
9 Z) n- I( t% @: V3 e                for (j = j0; j >= 0; j--)1 p- I& k# @* s! ?$ v' u" t
                {
0 v7 S7 @) Y0 O* p9 l0 L1 T$ H8 X                        /* floating date operation */
  U) U$ ^  U$ t' o- s                }
" W+ h; l8 x( e/ E9 v. {) ~
        }
: p% @/ X# w) E4 G4 U( j( H2 F9 j}  O" z. V+ n/ F% o6 f

- b9 U: S$ G/ Excorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样1 n& w) N5 J  p
( y0 {( Z% e2 Y; R1 f/ t( T
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
& q0 O. ?) l+ P! c9 ?3 }现在call xcorr 100次,耗时78s.: d% H  i9 q6 W/ m* ~  ^6 V8 |

# V) l1 c; g: a/ _如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
+ `6 ~$ B6 B; i
& c( H1 A' s  f- J" k) }5 [9 M
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
3 W* ?+ i( p; nMaybe Debug mode?

9 E- G) _7 j3 u
5 |7 i5 e' F- t; u9 ^不应该,看我上面的回复。
  E4 o7 M  p; e0 |1 U2 O& {6 w; F' Q4 y* @3 w% v' C* Z+ i' Z
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 4 w  J" U& ]' N3 Y
雷达 发表于 2022-9-24 23:54
9 R4 P  P, D, p% [void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 l) d9 [2 N; f{( f% `0 p$ V) e) a9 g
        comp temp, xtimesy;

3 k* [( ^; G# j  O4 O# F( h( N4 T% ?' [
这个不是这么比的吧。。。
9 Q) r9 {( M: Q0 E0 L
. e! d1 g9 N5 l* S您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。$ ?/ J( X  u4 t  I) s$ H. e6 p
/ J% g4 E. ?, m
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
" T6 K! _  w: ?/ }% Z
数值分析 发表于 2022-9-25 00:20
) X3 A8 h' [, G" @; G这个不是这么比的吧。。。0 o# W; s; w% a3 d
, v! W6 p. B. F. y$ \. h* ?) K
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
. N+ K4 a8 ?: I

: G7 m+ _9 _& d6 i7 L有道理。
7 y2 t. x6 f: K# @; V" }所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。8 {: s; H; _' L3 @5 n& \
3 a4 ?- x! Z3 n$ R0 w  f$ F/ `
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46" e" Z& i1 s5 R5 k! D- ?& J
有道理。# v' J+ O  I7 Z- S+ N) F
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

% m8 z8 V* |8 o你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多. t: T+ i2 e! D
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
; ]; f! J1 m; ~7 X( E, D3 f! o* u7 L这个不是这么比的吧。。。5 C" L8 F, c, H: h0 _, e: {! [

! R( h3 k$ E; y+ n+ w+ M# Q% Y您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

! s& ]# }- r- N/ I& A; B6 a- R: a. A; x1 u& ]
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 3 z6 P, m  x4 V0 Z+ _
沉宝 发表于 2022-9-25 01:48  E6 v8 O; j' D2 \
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

  N4 I. F7 b& F: ^) [# @+ O. j$ g
是的,兄台说的对。
7 \/ t- A5 p8 V+ V8 c" g7 F, F$ f" A0 b% Z% W+ L
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
, P$ I5 \1 d( A- A7 ^! j, @" M3 u
; O0 A, P: r$ ?. J9 y; z雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。# J5 g! q, I! J/ A
* h; z' ~. T! ?1 M
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。: G, Y/ k1 [* {

/ U3 N5 x" V3 Y& Q2 {当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ( w- }& r' g, z6 W9 J3 i0 `) S4 v
沉宝 发表于 2022-9-25 01:27" f! w" [' A6 I$ |9 J
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

) |; z. p: b) |- v: @* f  d) a
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
! h5 i# j: H, g$ o3 t, ~5 a/ [; q- Q
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
, b5 m! R- G7 z6 P( T又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) W6 I; N& g) C
时间差一倍的结果可以接受。
- m" V  {* ^' c
4 r9 P  x3 G- h" W! L. {你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 % D1 A* M8 U( L9 Z1 \' P/ m  g
雷达 发表于 2022-9-25 04:47
# {" U1 n: U: X' E% r又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

( [& s: v7 H$ U  B* s  z& i* E( G) _" ~/ S

& C) Y" i! [  ]# j  Y  ]/ j. e+ ]; ^- `  Y
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ' T2 f. I3 p. s) v( K
数值分析 发表于 2022-9-25 14:580 p5 a- H8 P1 Z
能不能把这个也贴上来,看看和上一个有什么不同?
5 s4 K; V5 x* H
理了理思路,重新做了一个测试。. d/ d- k* X9 C7 U0 j+ p# H
做了两个 vector 和 两个 float *, 都长 100000
( I7 W, f9 _* c外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache./ n: X. G- ^* A; b. ]5 ^% x8 i) c! v
; b2 w* x/ C' S+ |
内循环试了4种方法,
: T9 N# P6 l/ p  T  n" w; G; u5 x1. 直接调用 vector inner_product 247s ' Y" k' o1 b+ x9 B' \8 Z) U" S9 X; R/ l
2. vector 循环点乘累加 237s% R% j! l. Q* [. a
3. float * 循环点乘累加 204s8 {; e4 @9 R$ A$ c4 ]" `
4. 空循环 100000 次 202s5 p+ F, V* C$ {, _
  Y2 ~5 }7 l& j8 f$ n
不做内循环 200s7 J) P& o9 I: V. a" I
* h8 T% j2 o8 o* B) o: j
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
; p) w: Y; ?+ q' t/ r  J3 f另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
# P( G6 o/ H$ A3 O: t1 s
. z- |. G4 b, V- b- E- N至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)% v& r  b1 [2 O! W

) a! e" ~4 Y1 F9 D; j(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)& k1 f4 Y" n' w9 M( x

- U8 s! t. C% [& X
        std::vector < float > vec1(N);
9 Y: I$ ~; ~! z2 P- k5 E6 \; [* m2 \        std::vector < float > vec2(N);9 Z0 w- [0 [% N2 D. |1 ^
        float* b1 = new float[N];
; e' G4 }8 x7 H: M$ u        float* b2 = new float[N];
2 {3 @# w' x5 w+ d$ g& ^8 z" A, u8 z# u4 i
        for (int j = 0; j < 6000; j++)
. d5 c4 |5 d8 [        {; f1 d" B" X% U5 a! v
                std::generate(vec1.begin(), vec1.end(), []() {- j  m- n% a2 @/ n$ c3 k' m/ Q' E
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
, |( C3 X& O/ `; ^8 `                        });' F3 X$ j8 w. o- Q: z6 j9 P

% m+ P" ?7 m. q- \8 H6 X                std::generate(vec2.begin(), vec2.end(), []() {; ]; P# n: J! I7 E+ U; i8 D1 P
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
9 Y0 H. q9 y, d* K                        });7 o2 u5 I0 b6 B( I. y

8 a% I6 R. K8 ~3 i# o' `                for (size_t jj = 0; jj < vec1.size(); jj++)3 h% T+ R% Q# r& R" \- ^
                {
% \! q2 L# e7 F# ^8 b                        b1[jj] = vec1[jj];+ B! }6 u1 d. i# H1 x  w& h
                }
) r. f7 v1 L9 p. D# M) b1 `% l+ a/ C6 K  K" }
                for (size_t jj = 0; jj < vec2.size(); jj++)1 ~: y: _, K! ]) ]  U" y* [
                {
6 v, x* z/ }/ \/ ]                        b2[jj] = vec2[jj];, j. E# F% F1 R
                }1 ^5 ?0 \* S8 e+ R& b: g+ L) d
4 Q2 Q" [+ K* x1 `
                //Method - 1  N=100000 247s  
# |& J8 e) q1 w8 E. T+ w0 s: H) `0 y  N                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);% |0 M0 l4 H2 Y$ u8 d$ V1 u! S# r
                                
0 g! a4 }7 K! `                //Method - 2  N=100000  237s& B5 i  J5 c# r: m
                /*' t; i( x' X$ ^
                for (int jj = 0; jj < N ; jj++)- t8 P7 [8 H9 m1 y
                {
5 D: f& `5 u* i$ {                        fresult += vec1[jj] * vec2[jj];4 r5 @$ k2 f$ b; I! T2 I
                }/ h8 F  T& y- K8 T! K8 I
                */
, U/ e% i- @  y3 |  A                                - ?  M$ L9 [3 y2 n$ P/ \
                //Method - 3  N=100000 204s
* M7 E* m( i5 v; o" U1 y/ V                /*
2 E% y3 {$ T+ ]) Q4 j0 C3 F: [                for (int jj = 0; jj < N; jj++)5 X7 h8 Z6 c  A% f9 t
                {
0 k! ^/ R) _7 Z                        fresult += b1[jj] * b2[jj];1 H& I  Z) }$ M! d  s: V
                }
$ P5 Y6 x9 C6 a  }; L' m; z                */
9 F4 ]" Z1 p+ m5 B7 s; i
& @7 q+ x' ^; X! K  g                //Method - 4   202s1 ?1 Y5 o. ]6 H0 n5 O- c& Q3 D7 G
                /*7 L- T& H$ B3 a
                for (int jj = 0; jj < N; jj++)  B( s! u3 Y$ C6 d, B
                {
; T6 \8 J% n. F. @6 ^+ }# S9 {                        
& B2 E: O$ l( p& f; ^& _8 I8 j                }
- \0 k+ {1 i3 ~. P                */# _1 A! v0 Y  `% R9 l7 l
                //comment out all methods, N=100000  202s               
* h, X1 |! z: X% g8 {  P  a        }9 A4 f. \1 B6 h2 R

! ]2 X# J) i* V9 K2 l) ?. D        delete []b1;$ x+ h3 I* ~( p: M5 X
        delete []b2;
4 b: K0 m* l+ x

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?: T2 e% H) a1 V  M% `$ O1 Z7 T. i

/ G; I( Q+ h- G% M7 J你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
: x% A# \. }) e  ^, O
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
8 G! x8 {, E; w瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
2 [1 i; a. [, P6 c% k, h' O4 Z9 d3 c' A1 t! U  r
你第二个试验里面的j在循环里面又重新定义 ...
$ Z: H/ X$ O8 Y) u
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
8 s! W( }7 {- p1 }! O: T" k" U
/ d; `- }- ^3 [1 d! y不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
- }2 q# J& P9 [0 }4 _* N" H: d内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ T) R: W$ Z" s4 J4 p0 m8 E$ E1 ^
7 C5 K5 G$ Q/ V/ S  e8 J2 Y
不和它 ...

$ r& M9 y3 w2 H' K
2 _0 M- f$ a0 u2 `5 J不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。. R# _% `  b6 S
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54' x/ X. _9 q/ b/ }* D7 _% _
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
4 A! E& c3 E& z! _{
% y" u# f' {6 `" g% [3 l8 N        comp temp, xtimesy;
- ]" f& n2 j7 ^; k* K3 c' q
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。6 U% N# x0 H" A
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
$ ]3 Q$ G& N: O) q2 e; FVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
$ ~4 r# u4 [! _3 v9 n* k% J, {理了理思路,重新做了一个测试。
$ T3 ^" A' z' i6 [做了两个 vector 和 两个 float *, 都长 100000$ A  d  E' Q" n% k7 A
外循环 6000,里面先做随 ...
# f- X8 @6 N, ^8 l, q
这个时间是从哪里开始算的?
0 i' U0 _! g' [# y我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
8 J5 U. c2 [9 _7 S8 e1 W按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
  W8 O2 G6 V2 I) j这个时间是从哪里开始算的?
4 n! V9 z0 _2 n: r0 W  N0 O3 `我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
- ]; ?( O% T! I% `4 x' t6 @1 I
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。1 R6 b: {! `* T% X+ P, ^% C( |
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。$ L1 H" c) V! M/ ]7 k) y
与此对应用数组(指针)花了2S
# o. C% V! n; h( d2 O3 h+ Z; i1 H4 i你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
* Y+ j1 g1 G9 i$ ~: d6 K& Wvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
0 }3 ]/ G3 I3 y- L( V{
) B4 ?; g7 U! F; g        comp temp, xtimesy;

7 Q# x3 s; a+ C  X, o5 q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗& @6 _+ ~, D0 u6 c0 j) P9 j& |: e3 t9 i

% \6 ?' ^5 ~, ?. Y
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
+ k7 u; X0 z+ e6 F我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
9 z% L' T# T/ }9 V
8 S& l8 `' n# k1 z ...

7 X; l1 X: U! H2 o你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。  o& H, S/ q; w  r6 t1 L. {
9 l- u# S& d/ C- L$ t
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
# I/ R) P+ c( i1 o( L) c% @/ Y* |6 z) D% ]- ?' Q" X0 s
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
6 O) c+ `$ ?& [有空时我会试试 SIMD和并行,看看能提高多少。& F6 Q! d+ S/ U2 C- ~$ c6 c
过去7、8 年没有正经用C++ 写过东西,没有 sense 了
+ G* Z, p) |: ]( n8 Q4 j6 o  G谢谢大家的讨论,I learded a lot.  红包已发  
! P* L1 e! U1 w, B( i9 s( U5 e) P, l, M% h) l

- _0 ^* j: V$ u0 F! ^4 s- [% L
- b7 j+ W, {- j5 H; [: m! ^8 r  T2 D2 O3 e( |2 G+ r# y





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