爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?! f8 n1 p/ i- i$ p" ]

4 K( y$ o/ ~8 d# U& [) R自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。3 W# q" v2 a/ _: H
9 A- f6 X1 B- x3 _) L
速度优化问题真的很有意思啊。
3 g/ f3 z" ~: s& s$ E, y" v: k9 |$ u4 Y0 D6 A
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?0 I( N# i3 B; h: s; D( @) ]3 `; y
把代码贴上来看看?$ ~- B( R) S# C$ U- ~; t( F3 \8 c9 E
5 h% X* C; w9 X& Y
难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 9 d! c+ ]! G% d& s) z
数值分析 发表于 2022-9-24 23:04
, N: o5 {* s2 t* C& M7 \拉下来?拉多少?4 ?% o3 j) e  K9 t7 P
把代码贴上来看看?

) Y! F( o0 ^3 I% T, V# E( `
! W; A3 d3 n8 N& G' Vvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB), d+ u+ z3 w6 ~# j
{4 k) _4 A  A1 p  ?" E
        comp temp, xtimesy;
4 }  X0 M* B: w/ }# V. j- ?  k2 D        xtimesy.re = 0;2 }4 C' w+ g7 P( q0 |
        xtimesy.im = 0;3 R% G  B  \6 T+ k* R7 R
        int j0 = lenB - 1;
6 ~$ H* X5 B% H) k        int    i, j, i1, reali;. y( O, T- Y8 M6 c- J! D
        if (lenA % 2 == 1)
& y! M+ {+ E1 X1 z0 V# w% _                reali = lenA + 1;
/ e2 V; F+ t( a; Z        else
% _4 i1 ^( B) g) w" h$ j  E                reali = lenA;- e( |' z0 i9 n
        reali /= 2;
& a8 o7 B3 h1 D8 u/ T$ W; Q
2 ^4 J" g6 d6 K5 i        int nconv = reali + lenB;/ y3 S% \# N, ~
        //#pragma omp parallel for
. p& T( A6 m/ Z# f6 [        for (i = reali; i < nconv; i++)
( _  b- q$ g3 Q; \- U        {7 I( O# b0 `! ?" ]" z5 h) a- D# t7 s
                temp.re = 0;
2 o, `3 S9 T  R+ O                temp.im = 0;
5 ^( l  V' ?6 k6 G  u4 p4 `                i1 = i;
" Y: s' Q2 E' g% @                for (j = j0; j >= 0; j--)
" Y0 S3 {+ y& W& _                {; |3 @+ D  e9 r8 h& `
                        /* floating date operation */
# J; d+ K) u1 l  _5 D                }

" O# |" H1 ~0 j+ _3 m% K0 t        }6 g1 `4 m. {' j1 c  y6 Y# \
}
& a! a0 T  {* r$ [; B) l" E* t6 u2 ~; k3 H, A+ Q: G7 Y7 D
xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样7 O' b  u/ g  m+ p9 Y9 B* b- S
! A/ f& [7 q3 X/ P7 T
红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
& F: S2 K% B. g现在call xcorr 100次,耗时78s.
5 w5 d) k% x) [7 i4 m0 d$ i6 o+ V  Q9 P
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
+ U- n+ s* }) t0 p. z* O9 A4 h8 }; R* C

作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
" w6 V8 [7 g5 c* K; Q1 HMaybe Debug mode?
. Q5 A, P  P* u1 A; K0 H

8 M5 F7 ~  D% B% W2 i5 R不应该,看我上面的回复。
; ~6 k# H: }, \  H4 {& y0 K9 Y# d- ]+ S, C) h
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 0 T9 r4 x# G4 u6 U7 d
雷达 发表于 2022-9-24 23:54
: o! x0 Z6 v0 r: r$ |void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)) N5 n& p/ x# l. b2 P* u
{
( ?. F, K5 G2 h        comp temp, xtimesy;

6 O* W6 u$ ]8 F/ b
8 @) n; s; }" R这个不是这么比的吧。。。4 q0 ~, Y8 G$ S2 C0 l

+ X( s+ e5 X- F5 k3 ~: T" \& n您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。- r: z3 h# i8 z7 G- O1 f+ e

3 z) a8 b4 s' m而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑 5 Z- ?% T5 g% t' V& f, d
数值分析 发表于 2022-9-25 00:20( D1 Y! v7 K4 j! n% D9 y( n
这个不是这么比的吧。。。, d; n# `) d' w3 \9 \- [
* |$ ?6 _7 z7 y2 I6 M
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

/ V1 Z6 `+ J$ c, F1 a; b8 s2 s+ n+ w. s0 |+ q4 d# Z8 ^# B: m8 Z
有道理。: Q9 ~9 }2 c2 u6 i
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。/ ~* R6 V/ O5 b" O8 ~4 g

9 Z, ~* y4 t0 v1 r% o+ o) c& J我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:46
: j* _; C7 X; g有道理。
* J( G" [8 ?; W" U& I所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...

* l- P% r# j: I. M7 b) [: e5 w你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多; y, R& g, u, o
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:20
. i2 ~5 b0 _) l7 \这个不是这么比的吧。。。# r9 Q% h3 t: a# v5 d5 O
+ u: M0 ^4 S- c  p6 w7 E) d2 T: F7 j
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
* S% \% J# `2 A

; G5 A" {; `+ ~% X5 u5 o/ P现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑
0 ?* k! }  G0 _7 N
沉宝 发表于 2022-9-25 01:48
! G5 t5 _3 w  O/ {" P7 c6 ]! c现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

2 c. x# n& Q; q: z$ |" s
/ E# W) z5 }6 T' t是的,兄台说的对。. x& j# s' u8 @: b
2 e' ^8 U& a& V- |
其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
( D% T* R& t# w  ~! r9 R- n& G1 W4 P1 R: U) w- K% H
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
: h4 j% T. I1 Q- v6 o) j, A* t7 s
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。  S' ~& X$ |8 ]6 O
3 @; v* ]% o1 @& W( f- p
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
! X  v; B) z5 C9 o% J' N3 Z* \
沉宝 发表于 2022-9-25 01:27+ R3 Y) x2 J  m* T' `* M+ h4 c
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

8 C' H: ?2 R4 `4 w; E' c3 R' Y" @( D& w, J9 h- u
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。3 U- G  w* b' p  W

/ g1 _4 O- M; Z3 K我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47
( j/ h" j2 N8 u. H9 Y  o0 Q8 J' y又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
( O" p7 i1 y: v* {7 P. }
时间差一倍的结果可以接受。$ W' Z5 F0 }5 T) J
5 L+ ?) a, B+ Y% Q! G* S: u
你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑
/ S8 p. h7 P! {5 _! u# ?8 _# _
雷达 发表于 2022-9-25 04:47# Y3 N, z2 C$ s2 R6 p) P
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

. _& R6 E6 C, X: o, ~4 E* ?* G
3 W% N. s* Y  A
" ]- f! c7 T7 t0 m  E9 s! s) P+ R
8 a! E' V. e" `, B2 T& m! T能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 ' p( e" Y2 [. R+ C0 j. l# E
数值分析 发表于 2022-9-25 14:58
) J; z# _6 q& [+ k) {: T能不能把这个也贴上来,看看和上一个有什么不同?
3 ^4 B: w; z" H  p9 ]; {
理了理思路,重新做了一个测试。
& Z4 c9 y% Y5 w5 ^' H! ]2 H做了两个 vector 和 两个 float *, 都长 1000003 e$ M. e( f. Z+ D) O- n) ]
外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.
7 f; K  p+ S' Z: K" b7 K5 J. C
5 X8 Q" I+ U0 t内循环试了4种方法,
( g* P4 k) |5 h1. 直接调用 vector inner_product 247s
& ~" ?' t  B2 W: U2. vector 循环点乘累加 237s
# @* {4 r' `: A" ~3 n/ }3. float * 循环点乘累加 204s  M% R8 a3 J3 {. `! R' T4 s; X
4. 空循环 100000 次 202s8 O, W* _/ O& v

' N* m5 Q5 O$ y3 ~不做内循环 200s- X, Y7 V$ n$ J# s1 n" Q& ]- V
, U8 T, y! G5 \! s6 D9 z6 f) ~
你昨天说的对,内循环本身占比是很小的,大头在其他处理。! c' Q: D5 Z' L) }( ?( J
另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。5 T9 }  Q( w3 p7 E6 ?5 G
) I% N9 D* A. w
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)8 u% w0 I+ \6 G' M4 B# X

: H6 ~+ i% [. l! [; f(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)( `, i/ z* [! n+ c2 W9 ?/ D

; N+ K$ d, i9 {/ D/ z, j1 T1 l/ z
        std::vector < float > vec1(N);# }* F2 h3 X# V
        std::vector < float > vec2(N);
# X9 d3 {' t+ n3 {2 D: T, u        float* b1 = new float[N];& \/ m9 b8 G$ U9 x( W
        float* b2 = new float[N];, m0 a6 L: J" O+ r* u
" @" O. Q4 f: O
        for (int j = 0; j < 6000; j++)
9 C& J9 C" p) l7 v% H3 q! W        {3 y" F, q& q$ ^7 D' U# L. ]4 l
                std::generate(vec1.begin(), vec1.end(), []() {
' f9 y2 a2 l& i7 o                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
* V, O7 h5 _. T, Y                        });( i1 n  L) n# q( X- o# @! W
  M0 S* r) u( ]. O% C
                std::generate(vec2.begin(), vec2.end(), []() {
9 ^, \6 _/ l& E, J: y  B! [+ Z                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;. i+ ^0 M( g4 V
                        });6 w. H& j+ h2 J/ N" J* C' u: h% @

  |' u# x: @2 [7 u                for (size_t jj = 0; jj < vec1.size(); jj++)
0 c7 M. {5 U+ C                {: X2 {# [. J5 T
                        b1[jj] = vec1[jj];
8 u# ]6 i& |5 L; U) j# p! [                }8 A" M3 _: s. C" Z

' _( [: D  C% o) R                for (size_t jj = 0; jj < vec2.size(); jj++)
+ q9 @0 I. ?) m0 B2 i: [, C: F. _/ w                {
2 N! k3 X3 @4 j                        b2[jj] = vec2[jj];
7 Z9 Y. q/ K) l' _( S$ m/ b6 `1 s6 V' K& k                }
7 @. x% G4 r1 C2 D" V+ Y! I# `. O4 }( p9 \9 f( G  S+ o
                //Method - 1  N=100000 247s  
7 c: o9 Q7 N" B2 ^* |                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);) h4 q: f: p- u4 b5 C3 p& M5 P
                                
& V0 I7 m6 F7 o; t  ^; u7 E0 _1 c# Y                //Method - 2  N=100000  237s
% x, @" s6 r4 V. w% {                /*
6 J" ~( r3 b, h* }/ d  r                for (int jj = 0; jj < N ; jj++)
$ R5 O8 l4 _$ ^: d1 y/ d                {5 Q2 c& V2 |3 Y4 Y2 P; q
                        fresult += vec1[jj] * vec2[jj];
" v; p* G- }: j( T                }( o. R$ E9 J: j4 a  B
                */
+ C3 e& J- H* B9 z8 K                                
+ ?# Q1 V7 i; V/ m$ ?" k+ g5 E& b                //Method - 3  N=100000 204s
% J% A0 h2 V! C# q  ~8 {1 l                /*
1 l  H+ G8 f% m7 H" ?  w8 u4 ?+ U                for (int jj = 0; jj < N; jj++)6 G) g+ a: d4 z' S, ~1 p# @1 p" g- l
                {
5 \: R! S, W: m4 p% w                        fresult += b1[jj] * b2[jj];
" N  c: }7 C+ }* x, j7 ^' K                }! c% Z) _7 r, P+ s. p
                */
2 c7 W6 U  n5 @3 W3 E
6 Z8 {. a! K3 B/ B5 u: T% j; N                //Method - 4   202s
# Z( S& ]% k! ^1 p( G( Y: H5 `                /*
( a& g/ V; _) B4 i/ l                for (int jj = 0; jj < N; jj++)
) @/ c/ R9 x7 G9 M/ [                {/ q  l, N& ~# F- G2 ~$ `0 N
                        . J2 R# [: L, A+ `
                }$ j3 I. j, H9 f& j+ m
                */
6 e7 T7 }- C4 _2 P                //comment out all methods, N=100000  202s                  e# G* k/ S& d! {0 G' g
        }
; v8 Z! G) ?. ~) w1 P
/ V5 |9 Z! t. N1 |' J        delete []b1;
8 v5 P7 |8 y, m0 [        delete []b2;

% ?, d& P: g$ e" m3 C5 S
作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?/ C" a' k0 `; @% }
& n& {, J3 R3 R5 _! D
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?9 y# S1 W+ N9 w

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
. l0 Z  y9 t3 d. u" m. [* l瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
* g7 v- l, ?! D
# g; d2 a5 r, F) ?你第二个试验里面的j在循环里面又重新定义 ...

9 s$ `3 M# R7 o  g3 b0 E内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
8 q5 M/ m. c5 j" t1 r( z9 b5 e2 U/ b8 e* u
不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:16
8 F* E4 F3 ~1 ^9 Y, o" N6 ?5 r7 [内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL
$ G: _, G  o' ?, F+ ^+ X. h/ l3 v
4 _( P  x6 v5 G! t. @- l' n不和它 ...

& H" M3 h& p6 J2 Z* [1 Y" H* w& A
! q3 E, T3 Y7 z% d不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
# h5 F; Y3 b' c后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54
, o9 ^# U+ S( h8 M% \void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
1 ?8 v. Y8 l% c* |  ]9 e{
8 _  E& {/ H0 j$ O( x! a        comp temp, xtimesy;
. y9 L: }" k1 E4 k  G' O5 i
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。
& O9 z7 c1 L; F# p6 }内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
6 K9 ^7 s3 Q: @% h" I1 y: BVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30+ l1 \6 B5 y3 T7 d' N, H$ W! R
理了理思路,重新做了一个测试。
6 v: p  i1 g5 r" Z' z做了两个 vector 和 两个 float *, 都长 100000
- k1 m% O' q; |+ U- ?; N1 F外循环 6000,里面先做随 ...

8 O' @% ~* M! m" q  v9 Q8 \) S: ^: \这个时间是从哪里开始算的?
4 Q! Q! L- U% H  W% K1 C( Q我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。
$ ]8 a* c8 F& P  ?3 W; U9 u按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
  J3 t4 H8 e; g% r. x& d" `9 a这个时间是从哪里开始算的?
& I+ r, j1 Y) [我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...

3 M2 M2 [0 V& f+ Q( Y. E我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。
+ j; v9 x5 h/ `# \! E你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
9 s& b: L& N( _5 j. f2 L: ]& i" P与此对应用数组(指针)花了2S
( r; l: {" z- @* v" w你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:54  o6 }4 P/ j* `" z
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB); E& z9 ^( s, T. y# G5 c7 @; G
{
2 p0 M& F6 U/ n. c0 Z        comp temp, xtimesy;
7 C1 X/ s% j% z4 e  @% U
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
1 |3 a/ h* r8 A+ `& s) f! [7 a& c3 }

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:290 O/ Y9 n7 e: A1 r7 T
我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
: t" B4 p0 Q- k: f# C# S" b& I4 b
& W- o/ F7 ]% k5 a+ w1 g ...
8 w" B, M( V, e% B0 {% q6 G- t
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。+ V* J* @) {$ f2 F" B' N8 n7 @: i" n
+ w2 v5 E  D; ~
雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
7 J$ W1 R  p: j* M
2 V/ ]3 Q8 O6 b/ u: E. c8 g是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
' z  I2 [. P0 X9 w% R5 l有空时我会试试 SIMD和并行,看看能提高多少。* h% `6 u2 m; F
过去7、8 年没有正经用C++ 写过东西,没有 sense 了 . F+ ?2 p, y6 H( a
谢谢大家的讨论,I learded a lot.  红包已发  
) S& Y" S" c' \" Q0 g. [& Y
' L( R# r$ c- o6 l" s+ B" v) K
9 j- j8 I) T6 ]) T( Y: H

9 C0 V  c( Y# {) |




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