爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
+ A. n+ x" I9 P7 {! h
2 L) {. @% H  H- T' J4 Y# K  Z自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。1 h2 R) \$ K2 |% o, L: D7 E9 o
% L9 l$ ]( d' d, h5 Q) c
速度优化问题真的很有意思啊。
: ?( U- w' M9 E0 b- E
  x* g# G% r. o5 ]2 c欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
4 \+ J! S( F: Q' f! a% t: ^* Z3 w把代码贴上来看看?( z6 q5 p" i+ `
! ^( ]4 G, X6 X1 H+ v4 ]3 G
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 - S  d- |* n9 r& d; c* Q
数值分析 发表于 2022-9-24 23:04
% d6 p- h# C! e+ ^拉下来?拉多少?1 q- w/ B* r6 A; r4 l
把代码贴上来看看?

, N% Q( q7 W8 q# X9 S3 O) M3 h! q; q5 o
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
" q6 G- k; S: l* F. p$ Y+ f6 [{" I3 p! C$ s9 y% z
        comp temp, xtimesy;
  Y- s# O2 Z$ j) Z" L4 H) ^        xtimesy.re = 0;
1 _: P8 B$ _! [+ p        xtimesy.im = 0;
3 X( V+ G' d0 @        int j0 = lenB - 1;
0 J2 e) `& y9 }6 y        int    i, j, i1, reali;4 F, V) l* t9 V( c4 v
        if (lenA % 2 == 1)
. r7 P0 }2 a: t4 w& O) f                reali = lenA + 1;  N1 m7 @1 }9 I, m
        else" L- u+ J2 q5 m3 D! F6 t
                reali = lenA;
$ f- g* Q0 {2 k' R8 K( U        reali /= 2;
1 ~  f2 [4 n0 J  R2 J/ }7 B0 G; b$ g" F
        int nconv = reali + lenB;
$ C- V' Z8 }3 W- J1 {; o6 l        //#pragma omp parallel for, ^" i4 Q0 V8 S# m- P- u
        for (i = reali; i < nconv; i++)( l( N; i# J9 p# Y4 C* |
        {1 V# {) w# j( b* e7 W  \
                temp.re = 0;
* \9 g0 Z6 `' v: i- @- k                temp.im = 0;+ @& ]5 m) h4 ^8 t9 d- _; [
                i1 = i;4 c% H' V( e, d4 `9 K9 J
                for (j = j0; j >= 0; j--)
" Y9 c. S/ G9 C, ]* C                {
3 i/ t& {2 N$ W9 w' o9 E/ _2 C                        /* floating date operation */
; K+ F, H& ?3 q1 O                }

2 ~# W  d- s: \# _        }
% D, m6 d$ O2 o4 e* [}: }# J1 s6 g: h) T6 R4 f1 E$ n  N9 J) H
+ a' I! V4 ~7 E2 @# R
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
. b( ^# V0 A) X" i9 \8 ?& p7 d& u- c2 X( K. P4 Q
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
2 l- e4 s& |1 C7 c9 J2 ]/ S6 |! A现在call xcorr 100次,耗时78s.
3 y! Y3 _- F( B" D' P* F0 h
# Q$ o0 v" v9 u" h. T! \如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
7 E1 D; Q) V1 S- q& G& i3 i+ b0 x

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:333 q; K4 W6 o, E; d% n- m8 [) d
Maybe Debug mode?
  O  v( m3 {9 G# R9 [/ [$ W

$ x; ^; K4 I, l  a7 {6 S! Y! h: p! R不应该,看我上面的回复。
5 [; ^3 w: C6 Q9 o# R* }
+ e0 v, _4 m4 I# g我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑
" U' {: E5 ?2 n" M( L, f
雷达 发表于 2022-9-24 23:54) h+ ]# H! ^# x& ]) U7 W; S
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
7 A. q% o$ C2 ]{
8 X% c  Z' L) V0 c* W        comp temp, xtimesy;

+ a6 d2 ^; i  O1 y) J5 o- [2 P. ~: \
这个不是这么比的吧。。。2 `  t2 V0 K3 ]6 s- k  W2 k$ h

  u9 T8 c; n; |; z3 u4 t您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
+ q1 w& |) \8 E* t3 _1 z% W: W6 I- g! z% [3 s- \9 y$ d7 \; f
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
9 z8 I( b. n8 F* W" @, O& y
数值分析 发表于 2022-9-25 00:20
8 |: z: P9 u- C7 u0 `8 h这个不是这么比的吧。。。. q4 c% Q" a% N- F9 [

6 Z# _& j3 w" \您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
6 O  o0 J% f( u
* F2 ]7 n0 f% m1 u3 j( Y4 C
有道理。" l/ p0 F. @8 z% [& f/ j
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。" a" ^, O/ b2 N+ a) j8 ^3 k
) U# j3 Q9 `7 m4 L' E
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
; U+ G8 g7 S, x  d; `% |4 r0 `$ F有道理。7 S8 z4 o' }- [2 C; I2 p* ^
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

, O+ Q; t5 h9 i7 y  C" t0 r你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
" A  e% _2 Z+ @7 J7 e. uWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
! e$ {, C9 P8 R7 Q; S* G; {这个不是这么比的吧。。。! e) C; J7 v2 s$ P/ U. \+ i5 I

+ ~0 U9 ?- y  \* e9 v您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
7 x$ i0 c; r# w2 i
2 W5 w# A% W$ q+ H2 l
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
6 m% ]' ~$ f  Z" O, Q
沉宝 发表于 2022-9-25 01:48
/ d( J" k& e5 f" i现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
- t. l; J3 a$ d  u

, y0 i, C7 w% ?* G  c/ f是的,兄台说的对。
: W7 E% ^8 _% r2 i1 v( t2 S) g  ^7 ~: |0 ]  `9 j
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。# |$ e. ]. f5 E

. U& `7 i# _6 c. v# P8 {) t雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。$ G* E  ~# V  ]! J6 d/ W% a* y

% ^" S4 A7 U9 {- B: [$ V0 ^2 _比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。5 m9 N% d! l* C' _. G5 v1 r

" w: q% s; ?' Z" z8 l当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 & O! x, f9 C! i! V: L
沉宝 发表于 2022-9-25 01:275 W" x( Z$ I+ }* I
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

4 @2 x9 h- E! ^' U( ^0 J
# A. B( a( L% W+ o+ }. C' w+ ~4 [又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。, D# p' m: ]7 e! J4 D

. ^+ Z+ B9 J- y, B/ S( l我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47) u8 T- M$ l+ v' p, z
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
1 p9 T# W( T7 T, j
时间差一倍的结果可以接受。
8 N: ]! f% P) C' N4 t7 ]( ^5 u2 j2 L8 J' M% H! c) f) X
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
1 B2 v4 N0 W$ C! c9 ?6 B
雷达 发表于 2022-9-25 04:47
. r& R% |, a4 }又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

1 n) k7 W$ S1 I3 ~4 L# Q1 O3 U' y) D8 c
! X2 a( {. K* r3 w1 ~2 ?7 y

; ]9 y/ H8 ^/ \能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
* I/ s- d! \# @6 K. E. U' S
数值分析 发表于 2022-9-25 14:58
- V6 P! I% y$ d# I4 b  l0 j6 t2 g能不能把这个也贴上来,看看和上一个有什么不同?

  [( ^( Y- s* i- u# @2 B" g# f7 f理了理思路,重新做了一个测试。
% _3 C1 F9 r8 A# W4 D做了两个 vector 和 两个 float *, 都长 1000002 f1 N. m, m7 `) q+ n( V- l# t
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
- t* N" {) U1 X' _0 E# P$ @; j# O/ U( u" V# S9 I9 k" M
内循环试了4种方法,
6 T+ Q& Z$ l/ W6 b1 H6 [) ]1 z& V1. 直接调用 vector inner_product 247s 2 q+ e& I2 @5 _- u2 E, F- j$ c
2. vector 循环点乘累加 237s
  w+ Z- ?! Z8 ?" G& t8 n5 x3. float * 循环点乘累加 204s
; c% q' i' D* s8 R4. 空循环 100000 次 202s+ ]$ _* t% X, E1 l8 Y
, Y$ W& y  i/ F9 F& s
不做内循环 200s& Z; |4 W% a5 _9 b

9 \6 p. {2 H; `9 p你昨天说的对,内循环本身占比是很小的,大头在其他处理。1 U0 T, k# Z- ^* d+ J2 s7 s
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
7 u& H0 @! T7 Z: c% ~; M6 D( J5 N
* ^! ^6 f& m0 p5 |% w+ o至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)$ B& Q- ~* l' x: H" ~. B6 a2 q6 z
9 `5 ~  G; _& L$ N8 Q& C& n. y
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
% J5 ]* i8 `5 ^3 s# S
3 ^6 |5 z, \$ |# C$ Y2 H: ]
        std::vector < float > vec1(N);% p( o8 ]/ \( Y: w2 r! L$ b% o
        std::vector < float > vec2(N);
0 |3 X4 ~% v3 i, b        float* b1 = new float[N];8 i( Z5 z# `* E7 p+ G+ j: t
        float* b2 = new float[N];6 ?4 W" e4 L! Z7 V, [  ~4 B( e

, R; A( \. s# |        for (int j = 0; j < 6000; j++)! T9 [- N; h- G6 y  ~0 i. |3 X3 H4 ~
        {
/ e: X- D8 k& c4 E# j2 d                std::generate(vec1.begin(), vec1.end(), []() {
4 U5 g& c6 l: r4 L- J                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;5 q6 b& h% A. {$ }3 C! j( L# J% }
                        });  _/ j! N3 \, ^6 p
1 X) D4 Y$ f. f! f# l- t! Q9 ?
                std::generate(vec2.begin(), vec2.end(), []() {
' |4 U/ ?& d1 B* I3 W/ A9 u/ V                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
8 _; V) p7 s, m3 m. }6 i+ w                        });) @: [, U- L- l( ]) x' A8 z
- [, j8 p. z; j! X4 g
                for (size_t jj = 0; jj < vec1.size(); jj++)4 @0 b: r4 ?: i; ~& Q5 C
                {* G; ~  S- I0 U7 t1 y% t
                        b1[jj] = vec1[jj];
: n- G$ b1 ~) a% Z2 u- n) ?                }6 P; N3 m- y' h' D+ G0 d  a

( q( H* _- C- z9 s* f- D4 x                for (size_t jj = 0; jj < vec2.size(); jj++)% N! N9 a2 R0 }/ c# h
                {
7 b2 O' A( }+ A! k2 u                        b2[jj] = vec2[jj];2 U' U# X) S0 k" Y3 W4 B, A  q+ F4 u4 U
                }2 _! ~4 |; \' H. a; {
' m% U+ ^) |# z- h: W" k) o
                //Method - 1  N=100000 247s  + z0 C0 u0 n' n% a6 @6 L
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);2 A  f' A# E) p9 _$ H# K- i: s
                                5 X8 _4 D' r, O+ f3 {  @
                //Method - 2  N=100000  237s( X; q) r6 i( F. D
                /*
. B7 u( k4 t. J3 ^1 H5 D& a                for (int jj = 0; jj < N ; jj++)
3 p' d/ ?( O# v. @, X8 H                {
- a, H3 R7 [5 ~; m" _; i. V                        fresult += vec1[jj] * vec2[jj];
" a( ]- `* {! A  `2 ], [0 @" p; Q                }
. S* d5 e& W% j- c* l0 Y                */
6 }$ g# n( M  P3 |' z                                & I  S) n7 r# P) I: p
                //Method - 3  N=100000 204s
$ g' I$ u' N6 L6 L- |2 E7 I( k                /*
) O: z4 j' `) _3 N                for (int jj = 0; jj < N; jj++)
; ^4 t5 S0 g$ }7 d# M) G5 ]                {0 ~7 ?$ [) s; s; U) k" R' _
                        fresult += b1[jj] * b2[jj];+ @) l: z/ x: j
                }+ c/ g% A" p  C$ v/ ]/ m( d
                */
3 l. _1 R8 ~# A
! u3 m! g9 \+ d; s8 V                //Method - 4   202s
/ ]" K* T# Q" i) ^& q% p: K                /*% E" y. m% D9 z2 q+ I
                for (int jj = 0; jj < N; jj++)
- P4 s% K8 ~1 ^% B  A: Q                {
5 O8 o1 U: Z# }9 R! T: ]                        : w+ ?' s: O8 g
                }
, q6 d5 u+ R2 M( I  y' o                */
- D- @5 w- Q5 q* B7 k                //comment out all methods, N=100000  202s               
* q3 U0 j) u* W* I$ i- ?        }
7 H1 R* ^/ O1 Y3 I0 c9 V! P# O' |4 B- o
        delete []b1;
$ R6 a. N% w3 k. t+ C4 w        delete []b2;

2 `- D/ `2 v: @% v' U
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?; ~8 |+ g  P* H6 ]) O% y5 z* B( I
8 Q$ [4 J# N, J6 p
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?  v: ^6 E$ n! f! I0 Z

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15( \- B: |6 h- z2 @; m5 Z
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
) I. P" r) b  Z- r3 f3 G" \8 X* ]5 Y7 R6 V: H7 W& A- d
你第二个试验里面的j在循环里面又重新定义 ...
+ M! l* m( k# L- P
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL/ T$ \, O- K* x  N8 c) u/ p+ C; T

% G: c: t4 w4 @7 j* w6 i- n不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
1 Y! W& S; A1 g9 W) g8 n内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
; p, e1 e9 M7 o. y
5 Z3 S/ H' S% T不和它 ...
5 `0 N7 e" D* b% ]" ]
7 C2 G5 O- I7 P8 c6 W* F
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
8 s, J2 `* ]! ]  a: m  Y后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
1 y& c; k' u3 q8 Z3 F3 L. H/ O0 Zvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
/ R+ @; C. [* Z$ z. d3 }{
* n  x% Q4 \1 K6 d3 o" ]        comp temp, xtimesy;
5 Y( ?0 h1 t/ i6 O# k
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。, r: F9 o0 k: m! P
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?* z* V' o$ k  C; `
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30. a& h/ b: V+ d4 r
理了理思路,重新做了一个测试。- W. K# L7 @6 e9 W" F/ J9 ^! J
做了两个 vector 和 两个 float *, 都长 100000
7 u5 `3 o- W2 v外循环 6000,里面先做随 ...

7 k# d8 f8 c& T' h* ^这个时间是从哪里开始算的?
% d& d1 U9 H( ]5 c! d" H我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。; t) x% s2 H  V' M; @2 b- }
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
& U$ @, V; Y, e) C1 e' j这个时间是从哪里开始算的?& ?/ d# p) h% l5 }, I7 o2 t
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

. Q. F+ ?% H; y我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
( X0 M. {/ L% L7 `# F* I你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。1 i$ U2 W9 e; v; d; C. k4 ~
与此对应用数组(指针)花了2S
, z; l: x: H6 p1 g你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
1 r1 _# T/ W) s3 m. ^6 s( C0 N8 Bvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)! I5 H& Y! ]1 N
{
* o: G3 I5 t9 M! V- f        comp temp, xtimesy;
: o! `# [- V  f8 h0 I
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗, [! u! ~0 c' c, [0 V# A8 m
4 v  P0 q" ?8 R* q

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:299 W( R4 ?+ S3 W8 J4 ^# {
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
3 l- e3 B4 K$ c5 P  F' A. D
& o2 l% c) W! ^* `" T ...

* ^3 i2 b  e, Q& B; z你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。8 k0 S( u% K* x8 T+ y; n
! x; r% o& v8 u3 y
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
  `$ f/ _9 y% a5 M$ K9 z3 {
# ]0 K2 p* z. r4 k# K& A$ l3 i是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。# Y" A. v8 M2 @- Z* @3 a* G2 Z) b
有空时我会试试 SIMD和并行,看看能提高多少。
& u7 q/ v  v* e7 q过去7、8 年没有正经用C++ 写过东西,没有 sense 了
+ R7 H7 _- K& ^/ z" D8 ]6 f3 b谢谢大家的讨论,I learded a lot.  红包已发  : L" I: B& S$ L9 b) w: d

4 q; W/ M) z. x+ x; U  l. C( {5 F
& Q# ]8 Z& v" O; s9 t6 ]; x  M$ I4 I5 X3 b; @
( ]1 F: ~1 t4 ^$ \





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