爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?( L3 M& q. }+ y) ]* J+ I3 B( a

$ O1 t' C9 G! z: l7 f2 u# L4 s自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。; E7 ]$ e& b) }: F/ L
2 q: f& b, _, U: ]( W2 k
速度优化问题真的很有意思啊。( Q( A' O& B3 z, N7 L5 W* i' ^5 V
9 t0 V, B; Q; C0 B
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?% R4 J# O% ~5 @8 C0 ~$ r
把代码贴上来看看?" _8 I7 D$ t& Y( o4 A4 `

5 @4 _$ [3 k+ ^/ \9 e( K难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑
$ b7 l' a% S& }8 H' \. n/ ?
数值分析 发表于 2022-9-24 23:04' U. ~( V( q2 ^; F
拉下来?拉多少?
+ }# L# r1 d$ `9 L; \把代码贴上来看看?
2 ?  k/ Q7 h, u0 Y6 Q. Q
8 w5 S! j# E: v7 f1 M
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
5 d/ o+ Y# ?7 c! Q' O7 K{+ j8 ]: i4 L! q' _
        comp temp, xtimesy;
% N; ?' I9 O+ F, u        xtimesy.re = 0;
. r9 v4 E# R' y) ?# K4 g: F8 ~6 a        xtimesy.im = 0;+ v: W' m# c7 k6 ]- r$ n
        int j0 = lenB - 1;! k; G+ a; s. _' e1 i) Q
        int    i, j, i1, reali;6 ]6 [+ g; P4 E1 k5 ]
        if (lenA % 2 == 1)
, K% y" ~% x/ t                reali = lenA + 1;
: t2 }, ^) Y6 T* k3 D" Q        else; C. R1 o/ h6 m
                reali = lenA;
, J4 L( i9 C" F  B, S        reali /= 2;
8 {: d* b, G8 h/ s( N  @* p4 x; h4 {$ q
        int nconv = reali + lenB;+ X( h, p" b7 o1 b3 i$ `0 w( Y( W: l
        //#pragma omp parallel for
4 H7 }2 n: r" d" ?  S3 |        for (i = reali; i < nconv; i++)* C! T' c2 i' \
        {- _& I. M) k" Z
                temp.re = 0;/ Q& b! N- F5 y5 U% M8 k1 O
                temp.im = 0;6 Z3 A3 ]6 v2 ]
                i1 = i;
+ f: A8 R1 ?$ r1 _5 d+ c% |0 V                for (j = j0; j >= 0; j--)& p! W/ o9 ?2 _
                {$ Z" X0 K  o4 u1 \
                        /* floating date operation */
' Q3 c, r' i0 d& V: X* |& d                }
5 i- h( ^4 P5 R' Q
        }
0 c* G# \! u7 t5 K/ p" \}5 }5 H6 H  I  H. Q/ l
0 Y8 t) L. @$ x( x- c3 P
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
6 ^" d( z5 y) o( |" J+ G4 x+ q, X5 d8 {) m
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。. _1 |: ^! Y" f0 I4 j/ Z6 D
现在call xcorr 100次,耗时78s.
9 T6 W6 Z$ q% J  w9 l& T& w: X, n  g. D6 Q4 |5 O* M
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. $ S/ {& g+ n+ u7 ^+ @9 l0 D

+ x! s' S7 {% [  C4 ^
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:338 J0 X% O) z4 X# l" J, T9 F
Maybe Debug mode?
4 z' g, p  P0 m6 ?9 Q3 n
! s+ x. T( L$ q. k
不应该,看我上面的回复。- i, V- O; @$ x8 C6 q9 Q# V! [8 g: C. ~

" C! m: e3 L% S* c9 X- E5 A0 s0 V1 Z) M我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 : g1 D; ]+ A. v) W" }, e# {9 h
雷达 发表于 2022-9-24 23:548 R2 O: x" L$ f  S1 Q+ \' c
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
5 Y( v1 H' \. {- P3 w' ]& C5 C* B{  d2 U- V, G/ B2 t. x7 S( C7 ?
        comp temp, xtimesy;
2 B0 C1 |  x6 X" x) h+ ]
3 x+ j7 H' b4 C) B- V& v
这个不是这么比的吧。。。; J1 h6 n4 E- h
0 ]$ t' J4 @5 H) p# ]& L; T* p
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
/ j# \. P) C% N7 J2 ]3 Q0 {, I, e: f4 {9 @* F. o; ~. }
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
3 e& l$ J5 A, M! [
数值分析 发表于 2022-9-25 00:20, d% R" ]  N6 g3 Z7 l+ U
这个不是这么比的吧。。。' z! k+ ?9 W( G/ @

* {/ H  l6 `: p7 _  u) X& v/ E您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
5 T7 O  P2 K* A$ Y1 f9 t
6 O4 P5 Y% a+ a0 x( {0 B
有道理。
% ^' I; _. B: l, L所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
0 I" ~8 Y( x/ y9 R( m& D
( J! T1 `$ E' [$ M5 J: s+ L3 s" b我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:460 U5 r2 `% H) P
有道理。
8 }) k: E; S: @, Y7 M  C$ y所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
6 l8 C, w8 g2 \8 l6 C
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多" K& k5 ?' p/ m% q0 I
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
7 _4 `- }2 G( S! b" ]* y* Y1 a这个不是这么比的吧。。。; C1 Y. _2 k8 R' A. i8 \: R4 I

4 a$ a* |# Q- p% L+ p您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
  P- ]; |5 M, h- w  V
1 _  J7 R( y7 |& \8 u
现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 . W, S( [/ Z: c7 o4 P  _! V' X
沉宝 发表于 2022-9-25 01:48
; t; I5 W; |  _1 _- ^$ e* Z0 ^( R现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...
2 `" m  R9 o+ Q
* J6 p4 [) a" t! Y
是的,兄台说的对。
# }" {# k! }5 r# l" j1 u1 a/ e5 g( ^0 @
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
9 ?: P% U8 h8 }6 U2 `1 f' e
4 k+ z! [, p7 Y. v9 j$ \雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。* W  P7 G$ u# R
! [" T# ~+ _" [4 Z" _. i: t
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。! A" m0 N0 }$ g9 @9 L2 Z

8 X" w5 T+ V5 o0 t" b当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
0 o5 ]  U0 d0 ?4 }5 z! o
沉宝 发表于 2022-9-25 01:27* g3 _! q; v. \9 f
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
6 k- C, q: N: d! E: a/ J
1 x5 k. k8 h! T
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。0 ^( M" S. k# Q( ]; e" r3 ]( |5 e) t

0 E5 f) k& t6 B; w; d; I我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
- z7 q. Z8 z+ J2 t$ i又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

- x2 `: S; W! G! p: [3 f+ E( p时间差一倍的结果可以接受。
9 C- `5 M$ L! O: R  t) \
$ F* o* p3 e. T- c你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 ' D" S7 Z' l$ @
雷达 发表于 2022-9-25 04:47
$ |1 `6 O6 d  E又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

, b9 _& F* y5 Q* j. v3 q- j
# u) j/ X( L( L2 h! S7 \
$ |" T) a7 l+ U: n! l! k2 E; Q1 {
* p( J9 Z5 @0 S能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑
& \. X* }; V  M5 ]" e4 E' Z- L
数值分析 发表于 2022-9-25 14:58: T( }; q7 p% Z: @
能不能把这个也贴上来,看看和上一个有什么不同?
- a/ Z5 D' d0 m) s! w
理了理思路,重新做了一个测试。
: G, O1 \1 `* Y; }7 D! B做了两个 vector 和 两个 float *, 都长 1000001 Q  E* W: q; q7 r
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.7 S: [9 I2 i& ^8 X1 d5 K# A

4 m" b/ f  E$ v; Z6 _" p; R; C内循环试了4种方法,
: i- F' o; ]  o) u1. 直接调用 vector inner_product 247s
$ K2 b& R. z$ l# `$ h2. vector 循环点乘累加 237s
/ T) {4 z. T- X5 P/ z+ c( q- i3. float * 循环点乘累加 204s
; p0 f, W# p; Z4. 空循环 100000 次 202s7 N' e* _( y% r- L" [% ^: g- ~! O

$ s7 C1 O3 C, r2 V3 d不做内循环 200s( O1 p- [5 J" F; p9 t& I
; E( B3 r  X: X! p: X
你昨天说的对,内循环本身占比是很小的,大头在其他处理。+ R+ m. `+ X" e! G  z8 j
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。' ?3 s0 {. B$ M: j, O" E

2 D% U$ ?" b# S+ z" J4 t) y9 Y/ f3 k至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
' @% A. r( q# X$ L7 c; K2 K* Z2 o6 n8 V3 S
! z' D; c2 ~/ v" @$ L) T* `(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
4 Q- {( \3 s. Q* t1 T
3 Y* A0 e' i8 U. `; s6 f
        std::vector < float > vec1(N);
) M2 K- C  W1 f! @% a2 G        std::vector < float > vec2(N);
! ~6 N% g8 P2 ?        float* b1 = new float[N];5 u' F1 x7 }$ B7 v! {
        float* b2 = new float[N];5 _, p9 `/ J7 e: n

' q) T/ B" T+ U. q        for (int j = 0; j < 6000; j++). B! N- v) y: p: A, Y) H
        {! a0 e; z! _' ~6 U4 ~+ D! F" o
                std::generate(vec1.begin(), vec1.end(), []() {+ t8 K8 F/ x+ N3 l% |
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
, i+ |& z/ L& O% Q" H$ g6 E                        });
# z+ r* j5 L0 y& u. V8 O
+ L4 C8 O1 t1 q8 ~" n. U/ W                std::generate(vec2.begin(), vec2.end(), []() {( [  C  x7 X& g# o! O" X
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;! R5 s( A) L2 |6 \- H: w' n' A
                        });2 e4 e4 X# B6 ]" R" k- c0 t0 k& @
& `* Z4 o/ G; `1 F/ K# V% R' a5 }( K
                for (size_t jj = 0; jj < vec1.size(); jj++): f) D$ `, r& M9 V7 p' R! l8 `! j8 E1 z
                {) h  e6 b- H- R7 Q, k0 t$ g
                        b1[jj] = vec1[jj];
3 C, Z4 v+ r$ T                }; e" u4 _6 d: `) c3 i0 r
* l; p$ k# l2 m2 |+ T. R* ]
                for (size_t jj = 0; jj < vec2.size(); jj++)
0 \3 U- N; F" W! ?! W0 ~9 G$ X8 ?                {
- d( r# ]: ^$ i+ f9 C& r2 s) o9 ~                        b2[jj] = vec2[jj];7 k0 T3 Z# }5 w7 k( X* C9 P
                }) \' Q+ E4 O& h

. L  j) j, M+ l6 h8 j7 ?$ F' n6 @                //Method - 1  N=100000 247s  " r" s# x3 u( \8 g8 z+ h  Y  M
                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);5 J; E: ~5 Z# T& h
                                
- f/ g" h! x( C5 W$ E1 b                //Method - 2  N=100000  237s. m6 Q- |; ?9 L  @" ?9 Y) }- J, w
                /*
5 \+ ~( h1 t% @5 N                for (int jj = 0; jj < N ; jj++)$ S6 u* R8 `4 h$ d5 l7 m3 e
                {& K* Q- a8 h' ]: i0 c
                        fresult += vec1[jj] * vec2[jj];
8 {7 i8 D2 z# D  N                }
0 D0 V4 S, V" d# t! Q/ y/ S# v                */5 Y1 M8 n. h6 q. R  e
                                . p2 h- B# |$ Y( K0 _- \( j3 X
                //Method - 3  N=100000 204s
$ i2 C0 Q% d- v7 o& |+ R                /*
& g$ z4 j- S1 y$ w& F; T                for (int jj = 0; jj < N; jj++)9 L0 P4 @  Y" D
                {' Q  N7 w& S  L: O2 m6 t& }, ], F
                        fresult += b1[jj] * b2[jj];3 x/ L% l9 I; j" B, _* I
                }+ b, `; }- s" @
                */- R; T! o6 A* S- h* w  P
% @2 F- |! X5 \3 h
                //Method - 4   202s
  w' W6 U$ e0 A& I6 l                /*
0 z+ o  C: S8 {# d6 p+ d4 M8 ?                for (int jj = 0; jj < N; jj++)2 F( Y0 \) k7 F0 B
                {
, [" ]8 M' W/ e. P' C                          [, w5 \1 H% i8 n4 u, r
                }
* P& q0 ^# P6 p5 h$ o& r: w                */
" G" t' @0 c' W$ g+ ^/ u                //comment out all methods, N=100000  202s                # r2 w% U7 m8 x5 G- }
        }  Y- l# c( w, ~- W5 m8 \+ K
; t1 F* e5 h; Q
        delete []b1;
3 Q, R4 n1 k0 z        delete []b2;

8 b) |0 q& M0 \, x- V; @) ]
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
! b) X$ f0 ]( a- g7 g: E0 R9 a+ k: R! O) h. G
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?- }* x" ~; p9 ]" S

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
7 ]" m* ]7 \. R4 K* H* K3 m4 y瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?' p0 z' z: o9 {6 B* E" I2 X

# ?6 X) C% z) j% m你第二个试验里面的j在循环里面又重新定义 ...

/ A0 e: ?# s) a7 D) h内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
" e7 W; @) T+ K* Z8 h3 W
6 X: c5 h4 q. J6 N. `! F不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:162 r7 H2 d  i7 e$ V, _% j
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL5 a' l7 y4 `" @9 }# m5 b

, i# y/ |, |, T2 J7 X3 a: `不和它 ...

: {2 G( ?& `( F* u  ?; {6 Y
, J4 _7 Z% ^, J- u5 Z' G不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
- Z) e8 ]- @6 p! ?& l- W; f后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54$ }8 n6 _! t, z4 L
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
8 K8 _. ^7 X8 b5 a8 a1 x! D{
- Z2 N% Q% o8 K$ T$ h" }) J        comp temp, xtimesy;

. X/ O4 b# n, }7 e' X7 R这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
' Y( U" d. r7 b$ V内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?# l1 j' [' Z" K- W, @+ }; A
VS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30' P3 D# v- m+ n! s. J# e! [( g
理了理思路,重新做了一个测试。; W; g) {9 t& C+ @8 L1 }
做了两个 vector 和 两个 float *, 都长 100000
) ^. e$ c% E  D外循环 6000,里面先做随 ...

5 R8 H% o# I: K, Y' @) ~) b2 v这个时间是从哪里开始算的?
% J# y! z/ R6 d我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。0 j4 E/ ^4 y  i8 Q
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
/ c1 R; \( o7 d4 l6 j这个时间是从哪里开始算的?
3 G8 ^- P) |4 o+ ?5 i我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

) {' z6 `; a- a+ F我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
9 g) M3 F/ d  E6 O. E你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。) P0 r0 f# Q) @/ ?+ T+ s% y! e
与此对应用数组(指针)花了2S
8 R9 F; a5 s* M+ C你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54
+ c$ e. q# r& W4 y' m+ q1 vvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB): D+ @( G7 [( Q/ e: Z4 Y
{+ {1 k7 ]( h, [7 J0 F6 n% R  _
        comp temp, xtimesy;
  g! K4 s5 j% i) W: Q
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
7 M: n7 F, N7 h* g
+ _6 F; \/ C& V
作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:292 u; \! N* |  _/ c
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
# z* S1 j  Z) G1 N( @, G
) f5 l9 G# ~* D9 Y! F8 n9 ` ...

' l* `" X9 k+ }* V你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
  d1 A  _: }6 a1 f+ {3 n) _* |2 I/ E; L* |4 q8 B5 M
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑 9 q1 L8 @1 C4 @+ I& x
4 K8 K5 \- r/ n3 `7 U
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。( x. d) v( y4 o4 q% A1 }
有空时我会试试 SIMD和并行,看看能提高多少。
7 H! u- ]5 \' S; @& q$ w过去7、8 年没有正经用C++ 写过东西,没有 sense 了
+ m4 O3 c% @6 C2 k4 ?! D谢谢大家的讨论,I learded a lot.  红包已发  & j  A( n2 `$ W4 [% q

' [; V! l& C* f. J, q% J# V4 H+ C) P* v7 U" I. Y7 s
2 a" B1 D+ I) ]" ?- f

% c' K; Q+ C' F# j( s+ Y$ {& c




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