爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?* I$ ?! M3 G2 Q  [3 B1 c

6 V. H6 T/ m, G" Z' N" B# e# g自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
. a$ `, g4 b( h2 M4 ^" T. |9 [: |9 f$ p
速度优化问题真的很有意思啊。3 h9 ?  r: ]( h! P- [4 w9 f, f

5 h( p: q( ?/ u; T) V( q欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
% ^' j5 Z4 `, x+ |% l把代码贴上来看看?
- f6 s1 E* |- r) ]( D% L$ i% \8 D8 _9 c3 s7 D) o0 P9 I+ Y
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
: N6 ~& p/ L2 K
数值分析 发表于 2022-9-24 23:040 b+ u8 M6 {, k* S0 l. q1 J
拉下来?拉多少?
- i) h+ s% i; P. h0 n, M把代码贴上来看看?
6 x! u+ \# ^! Z2 [5 U: _$ j

2 _. m, o" `7 k4 R: F7 `: l: Avoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
$ I0 O/ i% i$ e& `: X{
% R2 M3 D' }! a7 i8 e* }1 L        comp temp, xtimesy;# E1 r- H9 C' i$ X8 B
        xtimesy.re = 0;% {% ^0 N* A- [9 @8 B6 Y4 e2 Q# W
        xtimesy.im = 0;
4 Q0 Q# N* [6 M$ S        int j0 = lenB - 1;# U4 u" \8 G! E# K
        int    i, j, i1, reali;
% _: P9 F, _! V- C5 @3 N        if (lenA % 2 == 1)  Q5 {# g- N+ |. d3 T
                reali = lenA + 1;8 i# K% L: d& r8 |
        else
2 K* a  u" }+ Q- p0 t                reali = lenA;! ]1 U& z! c( w# Y0 T3 w
        reali /= 2;4 |9 j) {+ y7 @$ {8 `+ Z! v: t3 U
( x6 ?* v: J1 i6 L9 G# A+ E
        int nconv = reali + lenB;
/ m+ Z8 f7 q) d- E; g        //#pragma omp parallel for
6 c. |+ s4 b) y8 w) j" Y        for (i = reali; i < nconv; i++)5 u' X' m" _8 k0 p
        {% h1 ]3 \5 l# j# x- ^- A5 z% C
                temp.re = 0;
( i$ h& K" H& D! H/ E8 t1 ^. {' F6 R                temp.im = 0;
- b1 o) i2 ?0 W0 D                i1 = i;3 v$ e+ X  K& g* _; _; i
                for (j = j0; j >= 0; j--)
, F( U# X0 X7 s, o                {
( J9 Y& \& |3 E                        /* floating date operation */$ g& o6 O# Y  p; P, E& g6 Q- c8 L
                }
0 _! d3 X0 J+ A" F& \2 r
        }
8 L5 Y6 ?: V+ g( ]}5 ]9 M! K7 I3 k  F6 i" @" Z
; M( `4 E: x, [
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
* t, f$ q0 L+ d
, {0 t# S9 Y6 z( O, ?! N& r红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。5 v/ @0 m2 `$ \
现在call xcorr 100次,耗时78s.
( R- _" m9 c4 L! _
/ G; [5 P5 h" R9 [2 |( @4 ~1 e$ s如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
" b$ t) |5 S3 `4 @5 }# p: P* q* `4 {- W8 z

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
% Y* ?6 j9 F" dMaybe Debug mode?

/ [4 D8 ^! M' P& l; t' G& |! J( _5 |9 l( T: a
不应该,看我上面的回复。6 ]  C  H8 I. s& \( P: F! G3 y
( W1 Z' U# ~; @8 f& m
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 , A+ N5 }) W$ o$ ]
雷达 发表于 2022-9-24 23:54& O7 i9 N( p% O, C; j1 I" P& X
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
( W$ G. O8 f& A2 S{
- M$ ]/ g6 F6 S3 j  ^7 @& M* r        comp temp, xtimesy;
+ A' \; l: V: ^1 E" P4 N5 B. }# B
- T% Y* K' I" L8 K5 _) n
这个不是这么比的吧。。。
5 p% g* |5 T2 z& K( \$ C8 v) n* c3 X! r. l! {& D: d. t2 x. f
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
6 Q6 w7 ]- w! F7 t& [2 }2 o. {: \% [. M" z
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 0 g. C2 ]3 f! i( x1 b* H
数值分析 发表于 2022-9-25 00:20
# Z  u3 ~8 C6 |5 p, G+ T! @这个不是这么比的吧。。。  b; `4 y; I3 n- z4 v

9 z  ?5 T6 x' }$ y- R# h您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
1 O6 M' }# n% ^1 a

& o/ Q$ P; v4 E# H+ I( @5 V有道理。+ e$ r5 R& f3 V/ k; N) W) E7 q0 f
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。, ^1 C. F4 j9 Q
# l. G5 R$ I8 a
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
+ \* F; U6 D5 O* z" t有道理。$ w2 S, K; \8 G, T2 q4 ~
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
* x* c3 t2 I7 J8 J" g$ N
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多# p3 l% E+ @9 a& s8 Z: x5 L
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
' @: I! ~  t# P+ c这个不是这么比的吧。。。2 O# Y9 \7 {# d6 {1 G

; f; t/ J$ m" Z" {; j. `6 {$ p您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个

" @6 f; p' w9 f6 j, Q9 f- Q% ~
( _( l; `/ n  ^$ K+ E: o* [$ `现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 1 P  k( v' Z. a3 B) e+ b  Y
沉宝 发表于 2022-9-25 01:48" Y8 H9 Z0 D. A* V
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

: ?  H/ x4 ^: e, ]* x7 @+ ?  R0 n! v3 s' ]% i, u- i7 u, M* ?( \: _3 b
是的,兄台说的对。
5 l7 K6 e: q: k
- a1 a- C% s! Q4 s  g  D/ r, W其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
$ ]% R0 g( ?. p9 ?
* t7 j5 w% t' b- e6 F+ m; o雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。2 ^) S4 c. u7 B  h3 s8 Q: C% ?. G
8 o3 x& |! q- T1 F: Q
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
) [: F, U, _7 g% n. }/ C
& V" O2 G) V& E, }; T' C% Q当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
! f. [. E5 O0 Z6 t6 Q
沉宝 发表于 2022-9-25 01:27" Y1 P% Q: }; k) g
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
# m$ S" g, w. b' }
$ K$ B0 u" n/ e- \
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
  y2 W" g0 U" z9 G: N2 W3 [6 L1 T4 T" }+ E
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47, d) b5 J, T7 J
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
$ g5 F/ j9 Z3 ^# e8 M
时间差一倍的结果可以接受。
' {+ ~, E5 H9 L- X$ |, h! C/ n$ N( W% a+ e: b
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
' _4 l9 f' r! b* M+ ]' _
雷达 发表于 2022-9-25 04:47* e, [3 v; A) l3 |
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

6 h. ~9 u' W) k6 R
* J9 F) [/ D$ q" w+ L1 c( X* j7 C- o# i/ I# c( w6 Y& X/ V

# P! N0 {, A; i6 b" B能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
! ]! V, a# H" w; t7 t( X( _4 f# g9 C3 @
数值分析 发表于 2022-9-25 14:58. _- p6 g: g1 R; G2 }1 f6 s
能不能把这个也贴上来,看看和上一个有什么不同?
! `5 A  P) M7 K* G6 n- m. x1 d) D- [
理了理思路,重新做了一个测试。  D3 ]" I: h1 r, O8 q
做了两个 vector 和 两个 float *, 都长 100000
) u% s9 o7 E3 Z) y外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
3 A! [+ @5 R+ J0 S4 b  v5 L. X! v& z; _  _% d) j, T3 v" t5 G
内循环试了4种方法,
/ j/ S; I! O* p/ z2 b+ F6 O1. 直接调用 vector inner_product 247s
2 V* U5 u4 f' K5 S( I  a2. vector 循环点乘累加 237s$ N' i8 I  \& @* o0 g/ D
3. float * 循环点乘累加 204s' w( x  k! F0 ]$ B; L1 Q
4. 空循环 100000 次 202s
6 o2 o0 F: ]' O% }
" }, X# p" M/ |9 x( x1 c& M0 ]6 h不做内循环 200s* `, I. }7 y+ u5 e" D" ^% F: H

& C! i. F4 p# U, T% {0 f/ H: a你昨天说的对,内循环本身占比是很小的,大头在其他处理。
3 F& A- ?5 @9 M! N7 P7 z: ]5 `另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
2 a( W2 r& _1 H; c- ^6 A
* k7 d1 R5 V& \5 l0 L至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
, P  x( P, F( j7 Y8 T( f
9 G$ [; h$ d: p(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
9 r" O- r+ h; U, W" O+ O* N* f/ e' ?- E+ {3 X
        std::vector < float > vec1(N);
( A: d3 X3 }+ q% }/ D  p        std::vector < float > vec2(N);# C$ N6 h) v: E" I* b( h
        float* b1 = new float[N];
5 O8 m4 V& X$ |2 q1 b        float* b2 = new float[N];# f$ J$ U2 c! }: W" e) R9 ]

' \1 q9 u) }1 d! A        for (int j = 0; j < 6000; j++)
% m  x+ e  X: |9 l( ^        {
! L, c: W- C8 c2 l/ G                std::generate(vec1.begin(), vec1.end(), []() {
' T+ S  P* u; P5 |1 |$ B3 {/ n                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
5 \  W' S; G% z                        });
- l8 u1 {7 D* ?5 o- ?# I
; Q6 E- k) s3 e2 D7 p2 V                std::generate(vec2.begin(), vec2.end(), []() {8 g, ]- _5 Z+ B$ x
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
2 p2 o3 i8 y& J. R  l                        });
8 n5 ?! X% @+ U( S$ y
: ^/ P1 P# z1 @* L; s1 s                for (size_t jj = 0; jj < vec1.size(); jj++)
- Q% r) N- Y+ w1 G' q# J  }                {$ d& h9 J( {0 w5 L" s6 [& y! l
                        b1[jj] = vec1[jj];
( Z, r: c, Q) h7 _8 w5 F& p                }
& S% g, r4 ~  ~0 e" s" ~+ ?+ N2 Z) B; E) c5 A
                for (size_t jj = 0; jj < vec2.size(); jj++)
" K0 `: H$ ^! |- g                {) ^& C4 w; g2 z: X2 L7 O: p+ B
                        b2[jj] = vec2[jj];
" o4 }* @. m" ]. j: z4 a: @* v0 ]" C                }. O- ^  u, {9 [. w) }- X

( d) F5 y& X+ o  [) o& I                //Method - 1  N=100000 247s  7 {4 I7 k( j3 E7 `$ V
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);! ?% v# h% p# z
                                8 z$ _; k" M1 L# f  g
                //Method - 2  N=100000  237s; c1 D( g! e1 R1 K9 T0 D
                /*$ ]# [- |: `; @' q
                for (int jj = 0; jj < N ; jj++)
# l3 ]% z! ]- ^9 u- T( e2 c3 D                {
, P2 f# E6 u" ]# y8 c6 Y                        fresult += vec1[jj] * vec2[jj];! n3 o7 i( K; R
                }
8 ?& M4 n: \( ?9 ?9 `( U                */  X  ^! f! W1 ]: B. S4 Y2 S
                                
4 ]- z( T# ?0 b                //Method - 3  N=100000 204s, ?" S0 D5 M) S9 [5 w. G+ S
                /*  ?6 z2 B  B0 S5 D( s* K; T
                for (int jj = 0; jj < N; jj++)0 ^4 A" U& ?1 Q: x  g$ o6 ?* p
                {
5 d% l! t+ h; s2 `$ e                        fresult += b1[jj] * b2[jj];
: i& z* W. p) t* D8 V# C. r" P                }
; u! b7 \$ t8 j: h                */
: C. i, S- Z! w( |, d: Z) [- H0 L2 X4 J* [# {# u
                //Method - 4   202s
/ F1 _5 K, E5 w* E* J0 }) {) c; P/ g                /*2 S6 A+ r% b3 q! [. p* v
                for (int jj = 0; jj < N; jj++)1 d$ @/ z) {' d9 o6 Y  A% d
                {2 x+ c' L" _, s& S( B! H: s
                        
# l- c& Y: ?2 a6 ^7 W! Q                }% U( j/ W' L: u) u3 g
                */
$ E1 [, b7 E& r; {5 O* {$ |                //comment out all methods, N=100000  202s                * O8 ]* x* {/ t0 O
        }) c5 n) s2 N+ k( n5 }5 x

; }  W- h& _8 C% Y8 ~        delete []b1;
' q' |' P8 B: u; J# G  g( y9 t        delete []b2;

7 |; h, k9 j% `9 X- V3 Q3 o& L/ ~
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
' u9 s- R7 g4 d2 ?( ?
. h2 D( G$ t2 [" f你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?
- C1 R: S' ?# E! Z& c9 ^
作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
7 ~7 _4 @" d. h4 P瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
/ k$ V; @  l9 E
' i" V: C2 k$ Y你第二个试验里面的j在循环里面又重新定义 ...
+ u1 u: A3 ^! {: b( M& o
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
" I7 ]7 C( O( I" O
4 J* R7 b, c3 J* Y不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:167 \" ~# y, B7 O3 U" Y* i
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
8 r0 w  m7 `/ g: N0 K' K8 I# {. z
) I# v; q; \9 H; X不和它 ...
1 y! a' L2 s! }$ n$ V: R
! e, J( a7 L$ i2 r! m
不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
2 k0 t7 v( T/ X) m7 k* t0 _后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
5 E+ B5 J) r( h9 |. |void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 J6 u8 }: b' g! C
{0 o2 t5 k$ C) \5 a* k
        comp temp, xtimesy;

9 D2 ~/ E; D7 u3 ~( K5 P) {这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。( I/ `' |+ F" p; r4 S) X" Q
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?# Y) T- L: Y: V, M8 v  {0 m) q0 R
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30/ ^/ W3 K5 _5 U/ c
理了理思路,重新做了一个测试。
1 b. D! l4 ~" a: D' _; k做了两个 vector 和 两个 float *, 都长 100000* S0 l. V" \; V  c" L" A" `: u
外循环 6000,里面先做随 ...
" W1 v4 P. M9 [3 V' E
这个时间是从哪里开始算的?
2 Y' J! J, H- K我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
- f' w5 L9 c% Z9 m5 }4 p按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39; m2 l6 `4 i7 m3 R$ ]+ b* `
这个时间是从哪里开始算的?1 n! c- Q9 K0 D
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
$ e2 g/ d6 K' v: Z# x$ Q- Q% Z
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。. c# w: G' E- Q2 Z$ @: j, l7 }" o
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
7 [- m" n- V6 y) Y" P* h( h6 k; b与此对应用数组(指针)花了2S
: I; m5 ?. D* W8 T你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
0 Q  L5 W% G: jvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)8 y% l8 P9 R; ^: F- C9 H7 P- t
{
) ~7 i  i7 Y+ s, ]        comp temp, xtimesy;
: M3 z- `( c; v) M$ a! H: F5 N$ z2 V
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
+ r0 [8 ]; `  {5 w8 r
& o1 g( K8 K% c% d
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29  V2 R- k8 F5 l0 l. M# x
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
- l5 X( C* i4 s( y+ ?1 d$ `
, t+ k9 J9 S% u! z ...
. ~- f# b, e; l1 o" ]1 M1 S) K
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。+ p0 Y: K, O. M* V3 ~" N$ X
4 G. I8 }0 H1 k- V) H
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
% R  e* }9 x( g9 E# ?- e4 f0 Q2 y+ F8 y. q% N0 p
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。: @  _; K) f/ t& ?
有空时我会试试 SIMD和并行,看看能提高多少。. \4 H+ \: @, R3 v7 D  f
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 1 Y/ |) j! S; _6 @/ [" {" |5 _
谢谢大家的讨论,I learded a lot.  红包已发  2 T* [' y4 D! S
3 |) V/ Q  [5 k
2 Q8 F! ?) ]0 i# B3 n  _# k, p

% \+ N5 g1 c& {, ]$ V6 h/ E) E6 C4 G





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