爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?" j) Z6 A! B( p0 s: c' \3 @

, p5 y: {" F" d) ?7 D+ z自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。6 M! T& t2 f1 t. \1 o! \- ?9 C) S3 P
- T( w) L( o, H1 |3 t# c5 F
速度优化问题真的很有意思啊。/ {: W& {; w2 U. A

2 h0 x' Y' B- b) z+ l( K' N0 u欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
. J/ n! ^, v7 h0 \  L% b! d把代码贴上来看看?  Q! p. ?* J( k1 i& x+ q
# G. B- x# c$ N$ t! B& I
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 0 r% f; J. I, G& A
数值分析 发表于 2022-9-24 23:049 w5 k' z5 Q" R; W7 r5 V
拉下来?拉多少?0 @) Y5 Z6 R/ w! i. d
把代码贴上来看看?

, o( [; x9 C2 ^5 R4 r
2 f" j1 Z8 ^5 E  Zvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
9 x& H; ?) q  J{( C0 b: t( K" s6 y8 B3 k
        comp temp, xtimesy;( |$ a  ~( e: e
        xtimesy.re = 0;
0 c, U; ~, a7 _6 k# m        xtimesy.im = 0;% G% |5 ^, a4 r) `7 c0 F8 n( m; u" D( n
        int j0 = lenB - 1;1 W5 O$ V/ `& n: S+ _$ N
        int    i, j, i1, reali;
6 \! H) T7 |" X        if (lenA % 2 == 1), _, a( Q- |, L
                reali = lenA + 1;
  o4 ]# w% r  M5 A4 r( Q& L! f& T        else
6 n* h( j% T% q6 E5 c                reali = lenA;2 @0 M0 G" s& G0 t! T' y* O
        reali /= 2;' P- r  d- D7 {- i) n- s

1 a" g: H/ m/ C' z* U- k        int nconv = reali + lenB;( I' i9 C# l, `0 f# z
        //#pragma omp parallel for9 M. d( ?) y/ H% q  k. ]
        for (i = reali; i < nconv; i++)& y; }( ?- H# L. X% _  i
        {
7 R/ g1 }/ i  x% H                temp.re = 0;
5 q( A  T% d3 |  P1 L% v                temp.im = 0;; ^1 o# l* _$ Q( p
                i1 = i;+ a* L* i2 \, k* X
                for (j = j0; j >= 0; j--), d: [' O7 ]1 o9 o
                {; C! {! |* W5 D/ u/ ^# y2 k
                        /* floating date operation */
# P4 o5 T+ K3 a6 P2 Y! l                }

; @8 E9 u4 j  c+ B1 h        }, d1 d$ ?$ A3 X/ o
}
" y5 X' [1 p7 C2 q* Q* e) H8 f% w, S/ |/ ]" g- M1 ]
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样+ L# c* k' M5 a) J0 B: N$ e

+ ~3 e  R- a" @红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
/ k  S: x/ w( K现在call xcorr 100次,耗时78s.) N( e, {5 N: l& B/ k& B

( @/ g* I% J6 H1 c如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 1 U1 t1 u; `$ x9 C3 X1 ^" ^# k: `
2 j1 \8 \! O1 Y, G

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
, Q1 a: k7 U. l5 Y0 F) P0 }Maybe Debug mode?

" V* }* C' m% [/ a7 U
7 r7 h% e# x6 S( t不应该,看我上面的回复。/ N: k" U4 u/ p  [5 M$ h

) p+ h9 b, o  U我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 ) f: Q% G5 D, J6 [
雷达 发表于 2022-9-24 23:54
* P. V. ]- m0 v" D* @+ \# Y" l) ]$ Jvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
. B) i3 @. I% ]& Z) O9 V  @# o{( ~# y4 [; ^7 D, y
        comp temp, xtimesy;
. \' n1 j) V7 u* N2 e: w
1 D& n: N" g: Q2 S8 n8 U
这个不是这么比的吧。。。
* T7 t+ [/ `8 u9 _7 V7 m" W) i4 H+ y. G4 s, u& `
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。- {: J: D) [4 _, d: }

( o- U' j% Q1 m; e  T; P4 q而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
: t# G$ q% S+ f# t
数值分析 发表于 2022-9-25 00:20; o" B3 z: @% t+ V
这个不是这么比的吧。。。
, ~3 c% a6 A9 D4 R% {, @# w2 F) @" Q
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

' a- `2 V0 l0 B9 N, f! ^* ^. I
( z6 J+ k6 B' o+ O8 h$ ]) J6 ?有道理。
, {& p/ o' x5 S- j% |- c! x所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。$ r+ K, l& L8 d3 q) E6 Y; @

0 I' e, T. d8 e* {我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:466 d5 u& _( @$ ~& \4 }8 m
有道理。5 V$ ~0 k. `+ B2 _
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
8 r8 W! V8 J7 V( H& ^3 V
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多8 Z' E+ l1 U  v! U
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:209 ^$ R# C5 K+ D5 C3 f
这个不是这么比的吧。。。; q9 N: ]0 v* l4 O' W0 V
+ K5 S6 U% I" d) _* v- S9 j% [
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

1 D' p! x9 T2 m7 `4 x5 d' G: X4 v! F$ `1 h% y, U
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
/ x* \, Y5 u; w7 }5 Y& {+ F/ X
沉宝 发表于 2022-9-25 01:48; T; ^/ r* @/ ^. G$ a9 D" Y
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

, r/ |  i0 @: C# p
+ H6 s$ E/ i5 ~& W4 r+ q  q是的,兄台说的对。/ @5 z. E1 M5 M; L
0 K6 z; A: R) [0 ]
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。2 `* C- n8 @1 p) G$ Z4 ]3 B

& N& K& x1 z% `$ `) N2 x$ n雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
2 _8 x' ~6 ]# s. V4 N) Y" u& x$ `8 z& V9 ]
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
8 D( f2 A/ K5 d7 V& H2 i( j! S7 n! J3 W! v
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 ) W- C- u$ H& W* P4 ~; U/ X. [
沉宝 发表于 2022-9-25 01:27' N5 J' P7 ?% `3 ^0 I
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
( V( \7 L. A5 C" q' m) ?

! l1 N5 Z% |7 F6 q6 w又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
6 F8 S- ~+ q" r  d# |; h# s
; z; p2 R/ [8 Z我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
$ F; H( Y3 H5 D" a又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

/ N# m- L, q) k: A8 d: @: X时间差一倍的结果可以接受。$ Y! Q2 l8 F6 A0 c( D
7 h1 T3 V9 Q3 X; T  ?
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 7 R6 e1 ]* A  X+ a: ~5 H& K
雷达 发表于 2022-9-25 04:47* Q5 h: Z0 W# X0 {# z
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
) f" O) `7 }8 X3 ~# n
3 R; ?$ b3 E- W/ M% [9 W
" {2 p$ y( Z5 U6 u) ?6 C( f
/ O3 P7 D" _+ Y' w" e% v3 Y0 K
能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
' W% s# V! b+ P, w: g( F) s
数值分析 发表于 2022-9-25 14:58
2 f9 L' d7 `& @9 L8 y, ^: ~能不能把这个也贴上来,看看和上一个有什么不同?
/ f; d! b. n& {2 V% h
理了理思路,重新做了一个测试。
# N8 L, W/ N8 I& x3 ~$ N* c做了两个 vector 和 两个 float *, 都长 100000
) A9 f1 T2 T- V0 e9 b外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
; S, @) B& h, V# e- u, h0 ?" {+ `1 E# ?8 H
内循环试了4种方法,
" i/ ~# u# f7 F8 _, |' a% e1. 直接调用 vector inner_product 247s / p) ^6 t9 H# {) n1 i
2. vector 循环点乘累加 237s" E, L) K' ^9 s& }; Z( r
3. float * 循环点乘累加 204s
  U: M; d4 c7 Z" X) {4. 空循环 100000 次 202s
: D6 @  l: I; y; v; j9 Z) o% ~5 c; i) o' q
不做内循环 200s5 m# h: h! S6 k* @: e) D
& C% y2 J  d: d; P9 |5 G
你昨天说的对,内循环本身占比是很小的,大头在其他处理。, F* \' O; k+ Y* a; R
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
$ Z+ w6 A4 k6 U( Q  l- d6 U  Q) Z  m6 B- g# [# W
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)3 P4 p+ Y; f8 f* G- f
6 R4 J0 b+ [! K, Q
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
# J+ O- f7 W  e9 p; s' {" s5 M% Y; r3 j$ O
        std::vector < float > vec1(N);
# ?9 g) _% U- H& c! R        std::vector < float > vec2(N);& g9 a( R: d0 }" R' B0 P- K! _
        float* b1 = new float[N];
% Y. y$ ~% a8 Q1 S# @  L        float* b2 = new float[N];
8 ~. s$ ^- `& W8 m4 |% O
3 Y6 V+ n# u# x! w+ u3 ?0 }0 _        for (int j = 0; j < 6000; j++)' Z. o1 \- ^1 h+ q3 j
        {
+ [; I/ @4 @5 k$ A( [* e                std::generate(vec1.begin(), vec1.end(), []() {0 F6 v8 ^' k/ H! `+ O3 p/ U" Q
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;4 `* B" S4 v! ^$ X2 _; K
                        });5 L( b. `5 S& r4 ^* t, D; }

! f, {0 u4 J- [3 X1 f                std::generate(vec2.begin(), vec2.end(), []() {
' L( M2 @# W6 J                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
2 m, y% v3 Q% D" g+ V' s+ |9 j                        });
% F/ I6 q' Q  q3 U
6 s- p" H1 L, i2 w                for (size_t jj = 0; jj < vec1.size(); jj++)9 j" I9 G3 v  V* Q) |8 ?
                {, [/ K& P- H* p4 P& Q" M# ~5 \
                        b1[jj] = vec1[jj];% h6 F" c0 D; M! A
                }
/ z( u4 j5 }9 c, q# R6 k! `
$ o- y" T6 e. w: p: k                for (size_t jj = 0; jj < vec2.size(); jj++)+ Y8 i9 Q) Y+ V/ C
                {# z& y: J/ N4 b4 g
                        b2[jj] = vec2[jj];
! V: i; d* F  R                }
; d/ Z' u/ X3 U# ~- T
, v4 u& h+ k/ j2 b/ d! h                //Method - 1  N=100000 247s  7 j1 S$ N4 I/ x! Y
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
4 R3 ]7 L. z. A* n                                - [0 S- j; }# g! t: y+ t4 n
                //Method - 2  N=100000  237s
5 V+ ?8 G% |. k: i8 I0 _/ t                /*
! x: [: K( H/ x! x) k0 }3 J! e                for (int jj = 0; jj < N ; jj++)
: ~: `/ }& H8 C2 K                {. q. H3 M4 P9 H  h0 R) K* [8 V
                        fresult += vec1[jj] * vec2[jj];
% {7 A- S3 {! k' C                }
  c/ n, K# e& {# l4 ?! ]: G2 K  F- A$ _                */; r9 t# x) u! m9 N
                                  [& o( x6 V0 W  b9 [$ P
                //Method - 3  N=100000 204s
1 T4 W+ m# K6 W1 V2 g                /*
8 o: w1 H% z5 T& h. _; [                for (int jj = 0; jj < N; jj++)
8 g% J7 O3 y  z+ k# [5 T/ m% y                {
/ ^% ~$ c( n6 [$ g. S                        fresult += b1[jj] * b2[jj];
; z/ j; p1 k  f+ Q                }' S0 W2 ?$ M* r( X& W0 \
                */  o6 G3 G' T4 }9 ?" Z9 b
* {/ u: g! n0 a! n) `- N% U2 |
                //Method - 4   202s
6 E; k1 k3 C4 B1 @3 N% m9 I$ j                /*
5 Q) o/ O4 c% a$ z9 k0 G                for (int jj = 0; jj < N; jj++)" `  X$ }+ ]5 a- U+ a7 q5 e
                {
- O. e: ]  K8 a& _2 r0 a                        
7 P) t; Q; O. q) O- e                }" @* s; o1 \" Z( @
                */
/ w. [* h! ?& G% f                //comment out all methods, N=100000  202s                0 ^1 q7 ]- j& L7 X* G/ ~$ A
        }
8 a% i; r+ `$ h: B! Q8 H1 b5 U
+ I8 c6 Y) u! O; F5 o  [1 F- a        delete []b1;
0 @5 }, N. l2 j# F        delete []b2;

( W4 r4 Z( C7 k. Z" f, I7 ]
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?$ Y3 H( Q# N+ d! t' A

: y* Y! Q; v0 T/ f$ `你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?; ^6 R7 _) ~8 K; y3 g

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15( r  g; x3 S/ v: H8 ^
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
9 D# v6 R  G) G, q; W7 ~
4 s4 q% a$ G6 a2 o你第二个试验里面的j在循环里面又重新定义 ...
5 A3 L$ Q1 R7 A4 d% z# n
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) s+ n5 c6 X* n& W9 ?/ q
# |2 V( h& M6 t' w' o# q$ y% w3 L9 u
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
  E3 e% F" h: k$ x9 s内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL) P! k/ ?8 c& t; _6 j+ a/ a

3 j( i4 E+ [1 c9 e( ]1 n7 l不和它 ...

; c6 o& h0 n1 ^/ j9 A) D
7 Z( k+ g/ Y4 i# ?不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。1 T& x" N2 e+ l) G% h8 q
后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
/ t/ ]7 h* `# T: Qvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)# R. k, H5 P" q( |
{# E* w6 `6 @* o% q& \3 G! s
        comp temp, xtimesy;
' B3 q8 i  |! o* m7 Q  H
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
! I- [7 Z  r, B/ s内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?3 x6 Q: S# A' g9 Y" q, V+ b; j& u
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30( P7 N( X8 P7 w- {2 T( S
理了理思路,重新做了一个测试。
' I: N; s0 p$ o做了两个 vector 和 两个 float *, 都长 100000
3 h$ U# g" M: ^外循环 6000,里面先做随 ...
4 G: {2 ]7 d* I
这个时间是从哪里开始算的?  W- q! Z! w9 p$ @% _) f
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。8 u( V/ N* C% t" a& S$ @
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39) p6 f  u- @' r0 R3 ^: F7 ^' c" i7 s
这个时间是从哪里开始算的?
, _# {5 d7 i! c7 t) q% s+ R9 p我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
5 _( u! [9 ?9 ]5 s/ v, ?6 C
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
! C  [5 O9 A. y4 p8 ]1 O你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
% l5 h- H" }- e; a" c与此对应用数组(指针)花了2S. L! K. ~9 J+ C4 F' J
你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
( P1 ]8 r% [5 }4 a: cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)( }/ s) i/ k0 b7 p' s
{5 m8 o/ R6 Y) f* Q0 U, D- A  p
        comp temp, xtimesy;
- A, {* i& l4 d$ [
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗" q; O. g5 p, g
8 |# `- k5 j# U7 Y( e  ~9 u8 R3 S

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29  Y9 d! e5 j  w; ~
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
/ X) I/ u! }5 t; n
4 K7 W4 ~; U- m$ M/ c5 j* w ...
/ V9 _4 A% d8 c
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。& {$ D- l/ x6 t. l9 v& w8 E" m
3 e& H7 V5 D/ B; W
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 3 s' m# \. j0 [, u
. \: Q8 U& h) j  b" X
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
! y! F  Z& l# B+ h' M0 m有空时我会试试 SIMD和并行,看看能提高多少。' e( D: b2 F1 G1 f3 h% I- P% U
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 9 a# r- i6 |" d2 ~* T% |3 j
谢谢大家的讨论,I learded a lot.  红包已发  6 C. D& a( S4 v* A) e8 ]) {) n
7 f# M  n& ?# T( L( H- ^) S

+ n6 _$ U" f8 q$ R$ m
- E% ^% U8 v& |1 M9 F$ b2 c+ Z( Y0 ^8 Z. [+ {* R) T! s- N/ I





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