爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?
4 N, F- e  h+ r1 t2 r) B, i, a1 g3 C3 m* @: T# o6 W% Q; M: U
自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
1 H2 c+ o+ I* u9 A+ h4 `* q" Q) z2 s6 h. w% h+ n/ M
速度优化问题真的很有意思啊。
. q2 R: o- \: V1 C4 K& Y
" G; r6 {2 }2 ?欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?: M0 t% D9 Z/ G, Q" y* z7 P, B
把代码贴上来看看?
: a  h. n3 r  w
; q+ X6 m4 z1 K- K, H/ Q难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 8 \4 g7 S2 Z9 M" n5 s+ f
数值分析 发表于 2022-9-24 23:04
. [+ A+ [# j: O- W2 }8 n拉下来?拉多少?
( Y: b; L; _9 r* D9 I, W3 @* I" o把代码贴上来看看?

/ ^# j$ J! R! M: T. `0 ]' H" R# x/ V" ^, x# ^1 U- T
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ x3 Y0 J) f0 V( m{
+ h+ D2 g# Q# }; m- |- S5 n8 r        comp temp, xtimesy;3 \8 p$ S" g: b4 \
        xtimesy.re = 0;& n* a# \3 Z, W
        xtimesy.im = 0;$ S/ R+ j. ]: z1 P0 t
        int j0 = lenB - 1;6 ~: A8 T. i* d; o5 k
        int    i, j, i1, reali;
0 J! z. q/ Z& S- }2 ]+ `% D        if (lenA % 2 == 1)
6 r8 v1 f# [: B, ?7 _7 g                reali = lenA + 1;
9 @' u% d* B" s' i        else4 _4 y* g! E+ e2 }8 o5 R% c1 x  E
                reali = lenA;5 b: _9 h9 N& l% \0 U8 ]; b
        reali /= 2;' O& y$ e8 x8 D! l

1 f! U" r' K. _3 S) g        int nconv = reali + lenB;- C! ^! `; C9 C6 s* E' b
        //#pragma omp parallel for
& E9 h1 x, v$ p% e, _5 N        for (i = reali; i < nconv; i++)
- u* K+ Y# h7 a0 ?6 z9 ]6 x        {
" I$ f- |4 B8 |. y. y, i                temp.re = 0;
4 `5 W: i. Q7 S1 ]0 f                temp.im = 0;' D3 t1 Q7 L6 m5 D" M. \$ c
                i1 = i;. k- _/ I, h* A1 H2 |7 n. P
                for (j = j0; j >= 0; j--)- R8 m4 B# Q% p$ b* M6 g8 J9 v$ s
                {
- K: }  {5 O! m3 [                        /* floating date operation */. v. u6 A9 u) H- n6 k
                }

; d' P6 }9 A# B4 U% X) w9 m        }
& N1 Y5 s; P  d* U9 c}* P4 H( [% X4 J1 u7 }

2 {! W5 `. _6 m" x+ vxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样, D. Z! r" |3 M/ N7 \, z3 S

5 N1 q1 \! Z, T1 Y9 v, A/ z红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。* S- ^! X# b- e4 x; N% i' o8 v5 \
现在call xcorr 100次,耗时78s.
- M, \3 Z6 I7 ~' Y9 `
+ n& I0 ]$ k9 x+ V8 [如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. ; l7 H' w. w' M% s3 a

- P/ u* v1 q! x0 u
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
# K+ Q+ N8 I: h# X: @1 vMaybe Debug mode?
- o* k4 t. r* F* {6 u) i9 p

' U# ]; R  ~0 w4 l8 r不应该,看我上面的回复。
8 t5 i! e- U4 @5 l
" F9 e% a8 S4 M( X  F$ {( D我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 - \5 z! L& l8 a7 k! L5 |) j
雷达 发表于 2022-9-24 23:540 A# A; W3 n$ H2 I; @2 E3 A
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ X4 k% J3 `) S/ |6 y8 A{. e) e+ s7 v. i* r( H6 N% p+ M
        comp temp, xtimesy;

: B& D3 _' F9 v2 R' B% q# k
! Q0 n6 c+ F6 h$ p& q9 `/ Z这个不是这么比的吧。。。% {2 ~0 w: W( B' F0 R  q0 y
7 V9 u$ B( S9 U" s* C
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
; [( L* o0 ^6 l" C) e# f- X, `6 M9 V9 G( N# |
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
7 [0 a3 b7 @- t
数值分析 发表于 2022-9-25 00:203 t, h1 S$ n3 [3 O1 ~( C4 a+ p4 n
这个不是这么比的吧。。。( d! v9 K1 {( V( Z/ M# ?

+ v5 G! z! d5 W8 q* t您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 U% S' d2 R! Z( c* l. \' c0 _9 ^

9 g/ {4 A6 x$ |有道理。
( b' i# `* h1 j& J所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
  J# g/ g& J6 N0 n9 r
4 z- H; b' r. Y我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:469 `. @' t# A1 e' O& g  q
有道理。6 T" p3 I. `# a/ g0 X
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

0 D7 T9 m& t2 @0 {% {你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多
8 t% v/ a/ R0 j  [" S% _4 fWhy is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
/ J7 w# Y+ K% _* ]这个不是这么比的吧。。。
; U" J1 U9 a7 e/ _+ r
8 r8 F$ b) r6 t5 Z6 H您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
7 F) |+ U6 Z- j! Z2 C% H2 E' `
2 z$ z. G3 X5 A) w: S
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 $ f7 C9 x! `& N3 W& B- j
沉宝 发表于 2022-9-25 01:48
1 x. Y& F! q$ W9 s现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

; g& v/ B+ X/ z4 G6 {8 M8 `7 V' s% v/ {' X# x
是的,兄台说的对。
. p& K" Y7 X8 U9 w, U3 ^. q, A  R+ U; b7 R9 M6 ~6 O5 W
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
- e5 m9 V9 C/ z
, i) Y6 ^1 L8 Y1 y7 H雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
6 e6 }* o" z& _* N% [! s/ B& T- `  e2 u2 m
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。& r2 ~( w# V4 \- D; o8 c
% t4 Z( Q6 S* P: o
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 % Q* C8 W+ G  \& Q6 s
沉宝 发表于 2022-9-25 01:27
& W. x- w! \, j7 Y2 y7 n' n) ?/ l你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

; d- n8 d4 ]% P8 [; Q
4 R2 ]1 G* W8 T' W  t又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
9 l1 `% T+ N4 {5 n1 w1 X# u6 k8 j$ M) N- w  D
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:473 a2 g( ~) _6 V" K+ D! r
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

8 s8 q  G" K0 j: h时间差一倍的结果可以接受。
0 D' ]- X. B( L. a0 E& l: a; m4 |9 A  ~% f7 G! L
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
6 P- `8 k3 P2 s0 [- {" q$ G. l- M
雷达 发表于 2022-9-25 04:47
! s) |( e' m: F5 p又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
3 Q6 X# ]6 S  L. ]

/ H3 y+ e  Y3 C3 F' ]% N
; Z, @  G/ _/ ^# k6 o8 [* ]
& c) |2 z6 O3 L能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 / ]1 L& }; R" X/ M: R+ M
数值分析 发表于 2022-9-25 14:58
5 `  u- k" X* f2 G能不能把这个也贴上来,看看和上一个有什么不同?

5 ^7 k  ^. w9 a" {9 k理了理思路,重新做了一个测试。
, t. S  x# K, W做了两个 vector 和 两个 float *, 都长 100000' _4 m: w* U5 h- h) M: \! ?
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.8 Z: I# G0 l7 K+ C. G$ B2 P% A, S

$ f4 B1 {& v2 ?内循环试了4种方法,
% {% @0 r) z* i. Q1. 直接调用 vector inner_product 247s 3 Z  ^  _! T3 h1 P' y
2. vector 循环点乘累加 237s% h" i% {/ r' }1 t& m# k
3. float * 循环点乘累加 204s% B' L% j$ I- C. [* [/ y7 T4 Q7 L
4. 空循环 100000 次 202s
" I0 m/ e( G) Q5 @) k, n/ |, C$ m3 T1 p& s% c
不做内循环 200s4 N: X( C! J5 [; {# j
) D8 n* l( f* o- ]  O' K
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
: A+ r! y) m" k0 }4 ]% i/ m另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
2 a& u1 W" _8 j" V2 s0 q7 P' _" C. X* s" }, e. O
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)' c4 j' [7 w; S

. U0 i" B0 z/ u7 @; }3 }' r" N(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)$ F4 X; e- G  t2 {
  a" Y/ C0 I/ b7 J
        std::vector < float > vec1(N);
, f+ z, u* h3 x  G        std::vector < float > vec2(N);
. u6 R: M6 j* T/ m2 c        float* b1 = new float[N];
5 I2 x$ o" Z& w2 [3 [+ K- l8 r        float* b2 = new float[N];
" X/ z) [2 V) r" L" @
2 q8 h1 h0 |, M7 a        for (int j = 0; j < 6000; j++)
" k6 s; A# I' w$ g/ ?9 u        {- n" Z. x* `" X
                std::generate(vec1.begin(), vec1.end(), []() {
5 O: l; M  C/ D+ O6 B' N+ C; q                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
6 {; ?( X4 P$ X5 F                        });
! P" V: J. k  B# s% [% c# C- u. `1 |( i8 X2 i6 g* g( I
                std::generate(vec2.begin(), vec2.end(), []() {; o# o( W( B$ ?8 z  D2 d; v
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;% `2 l' b$ Y+ ?" n: M/ h
                        });
# m% h" L" M. u* \4 n4 B
% ]0 D4 M4 b& p; M8 m7 b; j5 Z8 L                for (size_t jj = 0; jj < vec1.size(); jj++)( `  |9 I: v9 T
                {
% r: y  c* D8 g                        b1[jj] = vec1[jj];7 I, |8 R7 B  r! w" ]4 I
                }
6 u6 G# x- J$ n) u0 u1 n6 \( ?0 Q- G$ w  @. l
                for (size_t jj = 0; jj < vec2.size(); jj++)  c: a) }8 @5 O! K5 {  }( j* k$ p
                {
6 y5 a: g6 Y; C# V- w7 C1 c                        b2[jj] = vec2[jj];. ?3 N! Q: ^6 x- N3 y2 s0 f" {
                }2 Q2 R' C$ e+ j/ A
; Y. d$ \+ R) l; R/ r9 l
                //Method - 1  N=100000 247s  ' A1 k/ g# n, v& x
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
' |5 e& a% L& |  I2 V: ]4 g                                ; C4 D' e# }9 `6 x) R
                //Method - 2  N=100000  237s
, J4 i  y( t, M  A% t+ Z7 n  Q1 N9 I                /*
: T! Z0 ]3 d( G                for (int jj = 0; jj < N ; jj++)
. m9 v" P% |2 |2 t: B0 |/ C                {
6 u& d! |  H5 K& |1 h. n                        fresult += vec1[jj] * vec2[jj];% `  J+ I4 E! u+ H( Z0 x/ E
                }
8 t" _3 i. {) H                */) h& J% z: U  s" s3 v
                                
+ m% c  v& D9 U1 X! T                //Method - 3  N=100000 204s* {5 d0 d( l' A  m3 _1 X
                /*1 z& \; X9 a3 n+ _& A) x$ P8 F
                for (int jj = 0; jj < N; jj++)5 L; T* s: ~6 o, `) c
                {& p2 ^! Y1 G1 S9 S- m$ t
                        fresult += b1[jj] * b2[jj];% k0 h5 `- y. V
                }& L) v. f$ f9 e: p/ V2 S
                */6 @  E, c0 E$ C! |
2 F% q, }8 ?) B$ t. }' {3 Q3 K+ }
                //Method - 4   202s
2 Z3 ?: L! D7 j                /*
6 ?2 I( x8 E0 {/ B9 j2 e8 p                for (int jj = 0; jj < N; jj++)# @" }7 R" h/ w' o6 N7 s
                {
7 X4 H& u. @% a( b* |3 L7 v9 l                        ) Y2 C+ H% r* w, i
                }8 @4 m/ q* F* d' I  \( E
                */- N" _! s) H0 s) @! Y1 G5 C! v
                //comment out all methods, N=100000  202s               
- `9 a2 X0 @! ?( P9 A        }; P- t, ^6 j" G! o$ b" b- g

/ x8 m$ B8 P, F. k* ~. m        delete []b1;
& r! m- {5 f* ^5 x1 g- E$ \5 {        delete []b2;

7 T' P. ]$ v: t% |  M
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?1 \' F! z) J" H& R" {

: x3 T9 [1 h7 D0 y6 B你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
+ j  v- L0 R' m0 A. K3 n
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15. W4 {5 K0 z& N  G, R. U& J8 u0 p
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?; H- f4 n5 I+ P6 W7 Z
# c  R* A- I& e: i. H5 h
你第二个试验里面的j在循环里面又重新定义 ...

: u2 b6 m* W1 N6 h4 S内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
0 [) l. j. t# u/ N7 V1 n: |" K8 a" q; g9 x6 Q# e9 O) n
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
$ r. E9 o6 c3 s+ h3 ]) j' u内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
& _7 I7 N( ^! Z+ Q: C
7 n6 F& ~: B% u6 ~1 `: }- W不和它 ...

* g0 B4 D% l# N+ S$ v5 g
* G$ W" l5 X( i# b+ Y4 S4 Z  w不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
* }; x; q0 O) w) W后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
# t' D! x, ^5 f- u, S$ p/ w. d7 Fvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)% a- k3 _% ^# m' u; |% O
{
; l* T  ^& O( y" x* l" B/ `        comp temp, xtimesy;

: k# ^6 s1 I% g% a  a这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。. K' X7 R6 h: t6 `( D# ?
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?9 b$ i2 D0 Z" p! n2 E1 C" z8 D
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30' e/ u+ C+ J0 p1 t
理了理思路,重新做了一个测试。
$ T( w# C: D- [$ a做了两个 vector 和 两个 float *, 都长 100000% Y  y6 }8 R& W- f  |4 g. X
外循环 6000,里面先做随 ...

5 c- u# O  o. i, I, p9 K) N8 D这个时间是从哪里开始算的?
. ~; L( d: Q- w9 n我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
  B/ z' m0 n3 z) Z按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:390 n/ J/ G  H1 M( ]
这个时间是从哪里开始算的?
1 Y4 T, r( x6 ~' @, e8 e我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

; M1 \' o: E0 A6 N我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
2 O" G* e/ v) y9 J% q- E% {你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。6 \4 K. Z- @3 V1 k% e2 b
与此对应用数组(指针)花了2S
0 \0 m" u6 i1 M你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
" Z) d1 _7 b1 @! o7 D% W2 {+ pvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB), v) G$ n4 q( S. C0 Z4 Z
{
0 G1 |9 `" A7 g5 I" o! C9 X7 g        comp temp, xtimesy;
# o. J  C7 q' C! d/ R) q
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
, c- t4 C1 \, j; p9 E/ E/ X% @5 C% u2 O

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
1 o& c7 S8 a0 f0 x5 y: D我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
2 E5 W% \' ^8 A& ?' J' V# k. `. [  z5 j; y1 R* l" `
...
) q) D; L2 Q7 R( S; i7 k
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。# V% m3 \2 E9 _; e9 d: s1 [
# H  s# M4 \8 D3 X. z
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 - A8 Z! x  l" X! C

) U" U+ K2 F. i7 j9 B是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
3 D5 C" @5 S; Y5 M$ M+ \有空时我会试试 SIMD和并行,看看能提高多少。: y: b! I- y; S
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ( @1 v0 r2 q; }  u* S4 ^
谢谢大家的讨论,I learded a lot.  红包已发  
  e; ~( l: l* ?+ Y# T  f) S; c" E/ F5 n/ t$ V$ N4 z
) k- d% x) r9 Z
/ b0 {& k/ Z# H$ Q# B1 L1 e* J, @) O; k2 K

% z2 J0 D( g4 N  [% Z




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