爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?: R, c5 u2 ]& F% e7 l

/ a; ~, q; ^1 ~% ?/ Z% s( g8 I! V自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。* C# R2 B8 ?( T

  J. F9 l7 X. R( X! [' C* W  q速度优化问题真的很有意思啊。
! [, e( @9 N% Q4 L7 \* M1 Z! V7 y/ @) H/ o* x: f+ ~, n
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
. v+ [) l2 c' ]+ c$ O) j把代码贴上来看看?
8 G4 Q( o" I! v! q9 H$ G3 G
* O/ g8 Q- C! d0 X) J4 P: D& I难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 ! o1 j& ]; u; h- N% \7 y
数值分析 发表于 2022-9-24 23:04- R. V* A# P$ u; d
拉下来?拉多少?$ n+ Q- F2 a+ _
把代码贴上来看看?
1 v" E0 p/ G- `* l" R. ?, }
: X( X- u% @. a4 @; g$ E
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
  R( |$ Y) S5 N5 ]& N{; w# E' k2 K3 i  p) N
        comp temp, xtimesy;
0 w; K% E+ d6 B! ]$ q        xtimesy.re = 0;  l$ n0 Y0 a- d
        xtimesy.im = 0;
; H  y7 s; Z1 R5 C  e8 g        int j0 = lenB - 1;
- g+ m* m! P$ ]7 n, _. b2 n- k        int    i, j, i1, reali;& ^1 |( l* d' E9 W- p0 q
        if (lenA % 2 == 1)- J) v1 g2 f+ b, g( T
                reali = lenA + 1;1 l$ h2 v  i- m" h% N% F9 j
        else3 ]* B4 k9 z2 m3 Q/ p
                reali = lenA;9 h* T+ F6 ]+ h! A
        reali /= 2;9 J+ B! L/ A  ?9 D% V3 E9 G* K# b
% @  d% c% x3 ~6 [, r* g. i
        int nconv = reali + lenB;) E/ J6 G3 k, L. z
        //#pragma omp parallel for
% X+ V6 t6 X& t+ F' `        for (i = reali; i < nconv; i++), ?* }; Q: M2 Y
        {
! N  m& H! W) E                temp.re = 0;4 k/ V. @0 _, a* Y
                temp.im = 0;
) c8 @1 ^9 J6 J; [$ Y                i1 = i;" @* F% P; R5 k, q2 _
                for (j = j0; j >= 0; j--)
. d  C3 e  R; G8 y8 T6 ?% p4 s                {- z: r* c2 l. @$ h! _# V! ^
                        /* floating date operation */
! \. _& R  b, N3 N; |/ g                }

: e5 R% ?; l- _, n) p4 O. h        }
; O  {: D, k% e9 G9 {  T}
& o5 ^' ~8 f+ B: v8 u$ J% i- Y+ k! \0 l$ u/ V7 y: [5 z: Q
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
0 I: g" b4 ?6 s% H6 d, y6 S' P
# k1 E- c3 J2 G8 M) z3 A! ^9 {红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。9 R7 P& a& n9 O
现在call xcorr 100次,耗时78s.+ b$ z7 G3 s0 p8 w, k

* {) {. X# l% X. g. J0 t/ ]6 A! G! W# ]如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
/ \% l  g8 O' f8 z- N
6 j. c5 h3 ?3 ?$ p* g
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33' Z  v6 r- [7 E) ~# E, N, G
Maybe Debug mode?

; a5 I8 |0 {. y) r: e2 h* M+ g! R9 Z( e
不应该,看我上面的回复。
" H" }1 ^& l1 n6 a. V/ p8 g8 ~. K% x9 ?$ M1 k
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 . E% _5 w+ p$ ~0 e8 X  N$ |
雷达 发表于 2022-9-24 23:541 f% G% Z7 V. G. l+ j# P$ p
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
) Z$ P- o2 s( `' g4 O1 @{( S9 X2 P- L, a5 [
        comp temp, xtimesy;

5 i0 H; R/ J# k) Y  `; r
- ?2 A# j9 E9 q( C: Q/ l( K) t$ v这个不是这么比的吧。。。
2 o' \$ Z$ E5 g8 E2 N: _/ T( b+ S5 \
8 |& F3 l( T* [" ?6 p: W' V您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。3 |$ p( l' p' H2 ~: L& g
/ }6 ^1 f. ^4 G9 G& }/ b
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
6 B" i  d* t; A! e7 U
数值分析 发表于 2022-9-25 00:20
* ^5 d9 i6 H2 S9 ^6 q这个不是这么比的吧。。。
+ o- U& ^1 z& R) |6 d
7 C$ ]4 o1 Q$ Y8 y5 v) [0 O- h您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

* V% k4 z& r. U0 H7 k  O- i# N* O4 J1 f$ w$ L  V
有道理。
. U" r  ], D8 J/ z所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。7 @& |* ?7 Z5 r% B8 u

1 `; k4 B  x& q, B我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
/ S$ l' o8 g" ?" @1 Z有道理。
, P( J( x3 B2 I8 O* ?所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
( C+ k# E5 }$ C5 Q) V
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多8 n7 n' W+ w4 R/ b8 Q
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:200 }! \: E- ^( X/ ]& @0 \7 u
这个不是这么比的吧。。。
! F+ |+ F- B# ?4 F) h( g
+ T+ ~7 Q& l6 V) J8 f0 r" h) J您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

1 [/ u  x/ \/ y( q  k5 [# r* B: z0 p: ~: p( @9 y
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
# @8 O+ K4 e5 m
沉宝 发表于 2022-9-25 01:48
+ q0 t0 P! {4 d% [现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
+ e% p8 i& d* |4 o9 c0 N

: s7 z+ Z! y; k. M是的,兄台说的对。
2 _2 z. Z! N4 b% d) d, k1 f
! `5 r) f  A: W2 X" A0 J其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
1 u4 J$ c- u3 F* W
; D/ v" o4 i; V- v1 s7 b雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。! I6 e: t% {$ F, ~2 V

- j9 S( P4 `, O9 v8 v' x: s比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。8 Q% n' K+ {! b3 Q8 ?9 |
9 A8 J: S; L# x& B. ?
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑 . E  A. V+ y8 {# I0 Y* N
沉宝 发表于 2022-9-25 01:27
' E6 _; L' N+ o3 R- H. v* \% L2 ]( N" i你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
9 z! ~9 `! U: \7 N- P+ Y3 a" k

2 \% S5 Z. E, z3 u7 \, c( I) S又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
$ I" L; `: C! i/ M; Q" {" x& E8 m% \' |; ~9 V( x3 Z
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
# M& w7 @3 o4 Q3 n5 s又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
" N5 k* Z% _, l. V  t1 M
时间差一倍的结果可以接受。
: k; s  n. J# n4 {
3 }2 W, m9 o/ I你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 / N' @4 \* i8 z" n
雷达 发表于 2022-9-25 04:471 e  T* `# }1 K; h5 C$ O8 M
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

: \* L: o2 D) c8 e. E9 m# O
) |& T0 e4 I. j! E, |2 u7 V1 D7 p
4 R/ `! K' k  F5 b) z8 H/ Y7 R. e
; v2 s/ v  B2 C/ I  B8 Q能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 1 E; H& M) l( \9 d
数值分析 发表于 2022-9-25 14:58
8 s) t( h& n: \. o. q3 u6 L, L能不能把这个也贴上来,看看和上一个有什么不同?

. F; e, }+ E: O3 D; ?理了理思路,重新做了一个测试。3 T4 F" O0 b# S" {- O
做了两个 vector 和 两个 float *, 都长 1000004 ], C8 m; p2 I/ o& j, h5 O
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
4 c6 |- g9 ^  R! h% P3 j
) x) A. ^7 p2 p+ {1 P内循环试了4种方法,4 Y5 L+ \! H/ ?
1. 直接调用 vector inner_product 247s . h) j8 D1 [' P. x% O9 g1 R, y! x
2. vector 循环点乘累加 237s8 {; ^, @- S: q0 }) u6 H4 [0 E
3. float * 循环点乘累加 204s% H+ r( e$ q$ p+ @
4. 空循环 100000 次 202s. i0 z) e. l4 h: Y- Z1 r, j3 w2 @
7 z  a, u& ?$ e. R
不做内循环 200s1 V. m: {. E0 s! \
7 [5 }5 }9 \# x/ y1 |4 c
你昨天说的对,内循环本身占比是很小的,大头在其他处理。- s; x" i& l3 u( O3 x, d
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。( p, f7 H2 d4 g8 e% }0 |* `! v* _
5 N% Z' D1 X' |, X
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)$ c3 @! o9 }3 y# a$ e+ ^
7 O0 v4 W! ]- x8 b( [  x
(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
$ e; H: |) E8 @
& N2 @  D2 Y4 B- C
        std::vector < float > vec1(N);% U4 P, U+ ?3 i$ W2 [/ B
        std::vector < float > vec2(N);
4 l* H; B9 E! M; o# Y, C! v        float* b1 = new float[N];' {5 g, Z, e$ J( e# a
        float* b2 = new float[N];4 |4 ?* G1 v1 J
/ C8 X# w, l/ P  \- z; e
        for (int j = 0; j < 6000; j++)4 M& N5 P% i$ r( y) b/ v) [0 U
        {9 U$ H, }8 x; t0 C, K& E4 A
                std::generate(vec1.begin(), vec1.end(), []() {0 y3 X5 k" Z  M) H
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;- G; B7 J& Q9 R, W7 M
                        });9 c1 y( @  v7 j# G
7 O8 E, `8 a8 u9 z/ h2 E
                std::generate(vec2.begin(), vec2.end(), []() {
9 v9 H3 R: X- H1 `4 I                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;9 s. x1 E" b  F0 q" b& L& A
                        });9 g! [2 D6 F. {4 Y4 o/ h
$ L9 h1 B* R, t7 ^2 G
                for (size_t jj = 0; jj < vec1.size(); jj++)
6 _4 k+ Z" V5 h% H4 K                {( S: ~) O! b6 s8 V1 V
                        b1[jj] = vec1[jj];
) V1 U: O. l* m* Q* ?3 u; J                }
# G$ y9 |1 O3 `: Q; B0 t2 s6 ?6 F$ x% u8 @" @+ f  {% k2 _- j
                for (size_t jj = 0; jj < vec2.size(); jj++)
3 B+ D9 |! L% X# s& n                {7 R( w# u; p1 x0 \; D
                        b2[jj] = vec2[jj];/ }$ n+ V* [8 e! i) @
                }7 p1 q. h9 D$ o! Y8 A6 y5 {
( o: G' k  M, l+ |7 z: a
                //Method - 1  N=100000 247s  ! ]- M: G' T2 K7 g) F0 Z
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
" x" _* J! X, F2 I                                
  g1 Y: Q6 j; }                //Method - 2  N=100000  237s
0 N0 P7 f+ d( F1 [4 [                /*
. O) y8 ?0 O6 O+ D8 M# c) I                for (int jj = 0; jj < N ; jj++)
2 q7 j, w5 v$ @! Z: n$ |                {( V% L0 h. x4 x/ @1 }  K
                        fresult += vec1[jj] * vec2[jj];
& X- n' _: q8 U- F% B6 {, F                }4 ^1 G$ U* q) K, b4 e( z' E
                */; _- R; ]  j: g7 N# M9 v8 E5 t
                                
, _* e+ b# ^: P& G5 T6 k                //Method - 3  N=100000 204s
( q( W+ y, @  v4 J; o" H8 g% k3 i) N                /*
. p- i9 F4 [" |, ?7 F% z" V                for (int jj = 0; jj < N; jj++)- u" u8 ~; z1 N* ^# P( e
                {; B/ Y4 l4 }! X, ]0 ^
                        fresult += b1[jj] * b2[jj];
. e. I* B- B+ @4 B8 z2 t) i: S* J" V                }
9 ^' j& q7 A! t1 x6 E2 l                */
7 D6 l' }4 N* W- C% c5 W+ r, Q0 _' ?! o! U' D1 U+ Y) t1 O
                //Method - 4   202s- C2 W3 F4 q7 |: O! x0 {: z% K; |
                /*! a) G' ~( |8 R2 t2 B2 U6 ~5 f
                for (int jj = 0; jj < N; jj++)
1 C! s  v- {, V                {  v' @. \+ m6 ]/ L
                        7 S1 q8 F! ~# Z
                }6 c" `4 g0 D' `5 f
                */
2 n9 b( a3 j5 P9 f6 Y+ H                //comment out all methods, N=100000  202s               
/ n* n, C( r4 i* L; z7 j/ Z. W        }+ O6 e2 g7 X' n6 h& e& {8 Y

+ _# _6 Y: e- D7 a        delete []b1;$ V" k7 b; l: o7 V  P0 `
        delete []b2;

( p+ y% y% ?- e
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
: g. X$ j( X) M0 n6 f4 y% u+ O: q0 _/ {+ n" i
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?4 [" z# P6 C  n: g# ?! u

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
7 {- L! A" v. u( G$ B& q8 h) K瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?* c( @& s: g& Y/ s" U
: C: ?- D8 i, V" j7 q. N
你第二个试验里面的j在循环里面又重新定义 ...
  M. ]6 l6 x% j- t$ R
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
! o1 [. y1 w  S" K7 g" P! c: a
; n. W$ J. ?3 R7 m9 H, P" q) X不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16/ \8 }, m# c' D4 l( [
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL' u; P1 q& X* A* y% {! H

" W! ~! {2 l$ v8 Z. {不和它 ...

) U& `& l$ u! L) o: d4 I; U; K" M7 V7 ?( ~9 i, R
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
4 a6 _% ^" B3 s7 G, l; I后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
$ F8 J; U. P1 X/ E' i* e4 o( R. P* |void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)9 v7 C$ G. o- g+ D
{5 H7 v( C  ]2 h2 `6 ]
        comp temp, xtimesy;

$ l$ |9 E+ q% _4 K/ m) @6 ]; u这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。+ W5 g' ?5 X% X0 ~! ^/ W+ Y( E
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
' |5 L9 k2 F: f4 T1 l: zVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30
. C$ q$ B" H6 L理了理思路,重新做了一个测试。
8 Y& E4 J' @& e9 N, Y做了两个 vector 和 两个 float *, 都长 100000) {0 n* }) l* z' D6 x, D
外循环 6000,里面先做随 ...

, C" ^/ |( y6 E+ W这个时间是从哪里开始算的?
3 _+ p2 N) }7 `我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。. o5 n% x- ~5 d% T( j7 E
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:393 @4 ]! u" Z. C, A- j8 A
这个时间是从哪里开始算的?/ S4 V; K' F9 `9 B0 v* T+ @$ k
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
& O. q" y: A1 w* {2 i
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。5 c( p0 A; {- w% ], h
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。$ R& e% {( }8 J5 h
与此对应用数组(指针)花了2S
3 i* R& M. g4 |( N7 Y你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
) V3 z& o; b* c/ Uvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
" \) R! ^+ R9 P* @' u{" U) c5 i/ m) d4 {: R0 W0 c
        comp temp, xtimesy;

) g$ k! C6 r: _我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
7 k5 U3 T  x3 B7 f, w. h" j9 f
& E# J4 B7 D8 H% k
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
9 q; `  V- k! t! H我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗5 U1 a2 }  Y2 H9 q7 }2 \

/ }/ T- ^' u" J8 V# g' H$ \ ...

( m' @+ L- }. i' ?你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。) J# x0 Q& Z- O

8 L7 o. r: Q* Q2 Y雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
# X) n/ L9 k! [- ^" F' k* }$ g. t: b6 T0 m, ^) [% W5 l9 z
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
" x- O! L$ o+ n有空时我会试试 SIMD和并行,看看能提高多少。2 i/ _, x. F/ E- n! j7 n, p/ f# M
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 & c/ q4 n/ B$ j( H6 @! s4 N
谢谢大家的讨论,I learded a lot.  红包已发  6 q8 A& x6 u0 n9 B% T( l" H
7 o8 C' Y! M. l4 S; G. X

" q6 F$ {" P  z1 p) h! g3 S: |: g) i$ G) w" q7 Y( S
$ ^* F1 m/ c0 q" R; m2 w





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