爱吱声

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

作者: 雷达    时间: 2022-9-24 22:54
标题: C++ 提速的新发现
C++ 比 Octave 慢好多,怎么破?& c2 i! l4 a; J+ f

3 ?9 x5 r  y* I自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。
& K# a( Q, Z1 V8 X  S. O) P! K( ]1 p% W9 f+ C" S; D' G
速度优化问题真的很有意思啊。
4 q4 y+ z# @! U5 W, N- ^. }7 G, F, z& m8 [! Z' h9 E5 f$ f% f
欢迎大家继续讨论
作者: 数值分析    时间: 2022-9-24 23:04
拉下来?拉多少?
5 u- R% Q0 G" I8 x$ N9 j把代码贴上来看看?" M7 o6 H9 ~, T9 u

( F/ n  h2 F  _难道分支预测不准破坏流水线执行?不该啊。
作者: 沉宝    时间: 2022-9-24 23:15
会不会代码本身的缺陷阻止了自动优化?另外,硬件配置和开发环境可能也有关系。
作者: 风雨无阻    时间: 2022-9-24 23:33
Maybe Debug mode?
作者: 雷达    时间: 2022-9-24 23:54
本帖最后由 雷达 于 2022-9-24 23:57 编辑 " f; I* G- [6 D# b) [  C: o4 o$ i
数值分析 发表于 2022-9-24 23:04
3 w4 W6 D; j- M! Z  S4 R* M( ~拉下来?拉多少?
* d3 S# A/ p1 `6 @! _+ x  s把代码贴上来看看?
# s- ^) s3 c5 l) H
3 Q8 r& X1 s; T" S! ^5 ^* P
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
# `( Y2 c" ?7 I2 m6 \( b8 y+ V{
: v( o8 B0 P* U; Y; d6 Y        comp temp, xtimesy;
, L+ Q$ M. q6 M( n1 }        xtimesy.re = 0;
9 C+ `& Z! X8 P1 {( v; w/ a6 M/ E        xtimesy.im = 0;
0 b! [4 z. g( O4 G        int j0 = lenB - 1;
$ b( H; [8 I& J1 q6 ~$ t  H        int    i, j, i1, reali;
9 s; w/ R7 k  G" [0 l# x        if (lenA % 2 == 1)
, y; y7 D  n5 p0 a8 J& @2 b                reali = lenA + 1;
7 |4 e# T$ _3 r8 i6 S% q        else( h. i( e4 g9 t; v3 d
                reali = lenA;) e  C7 |3 a3 v# b
        reali /= 2;3 O4 E# D8 R/ _+ N7 g

* E1 e; \2 u9 i0 E        int nconv = reali + lenB;
8 I& F; {0 Z+ z8 o8 p) _6 G5 Z9 A' Z        //#pragma omp parallel for
6 }4 h6 ]- p9 r  ?        for (i = reali; i < nconv; i++)/ J0 w9 J1 Q5 U, Q. [/ R) u
        {- N  O9 l# P' _" k& j
                temp.re = 0;0 J7 L, X+ W/ f9 C/ i
                temp.im = 0;
& h* h( H- r! c  g) F2 ~" }0 K                i1 = i;
& m3 j5 G  v; R2 C. j3 X( e                for (j = j0; j >= 0; j--)
; R3 F% S& c( J6 W8 r; j, \5 @                {
. S4 Z2 k1 Q1 ?$ V                        /* floating date operation */! K' I6 L/ k4 V
                }

8 I# W  s1 u& c) C        }
4 k2 F% C' @  h* l}# P  F4 w& q- T( ?* A2 F  L* _( i

8 `5 n& H. N8 ^3 oxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样: j+ X% A7 P5 E' ?% @( Z- X

  L5 G, E% l" t& ~. c& q1 J: S8 a6 i红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。
; C7 P+ l2 N0 i; p% o现在call xcorr 100次,耗时78s.
9 e+ ^0 R/ c& n( R, `% ^3 U9 S' g; t& l3 l, Y9 g" L
如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s.
2 i  o1 Q0 [* m! J3 T+ G! k
9 _5 _/ d8 \+ W
作者: 雷达    时间: 2022-9-25 00:17
风雨无阻 发表于 2022-9-24 23:33
% ~; H: @8 p6 h3 GMaybe Debug mode?

% \/ M$ J! J( \5 i4 D* p4 E
' {0 Z: J! Q6 q( `- z% R8 g不应该,看我上面的回复。
! }2 ?3 F3 h2 P, \! \/ J. S& M. f7 `! i# S! x, z# G
我更怀疑是 VS 社区版的问题
作者: 数值分析    时间: 2022-9-25 00:20
本帖最后由 数值分析 于 2022-9-25 00:24 编辑 / }5 X% V3 M0 d' m+ w1 }
雷达 发表于 2022-9-24 23:54
7 O8 A& V* L8 H, P, Cvoid xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB): |0 `% I9 [/ S* \% D$ C
{3 b1 Z, ]1 D, Y  p0 w7 l* ^
        comp temp, xtimesy;
7 K* J' z+ y1 |2 X
# k* Y+ x0 V& U
这个不是这么比的吧。。。; `; m! X% F  r  _

/ Z$ x+ J4 i2 J- v3 W( k  G0 u您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
& x* T: Q, k/ s1 ]: x! Y% O/ H) ]7 u- a5 z
而加上内循环,光jmp和dec指令就至少多执行了6000个,慢个几十倍不是正常的么?
作者: 雷达    时间: 2022-9-25 00:46
本帖最后由 雷达 于 2022-9-25 01:09 编辑
( D7 t( O; K  ?5 A( c9 k# O! [3 K
数值分析 发表于 2022-9-25 00:208 a% F8 t- f' U& K" S" B( K" K, o
这个不是这么比的吧。。。
* @. A/ {% L  }4 y- O7 O' X0 ~
2 T2 S  Y5 y" a. h- E# x6 h您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

/ P& V) A( I% _! L: i; L6 X8 r8 C1 v
有道理。$ w% u; i1 a9 s1 |# i1 d- D2 z  f
所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。
8 ~( |' C0 O* c" n/ S3 B8 e1 Q( m  X: W! t8 J5 y* f- N
我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
作者: 沉宝    时间: 2022-9-25 01:27
雷达 发表于 2022-9-25 00:464 C( D7 `; P; N! J$ w& Q
有道理。
* i/ i$ z1 V% i$ ?3 o( I& b' W4 n所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,这大 ...
+ w( \6 B4 A( x( H1 O
你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子,把循环本身翻译成机器指令loop或dec/jnz,两者速度上会差很多5 E- x% K* x9 C4 l1 Y7 o7 b# q
Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?
作者: 沉宝    时间: 2022-9-25 01:48
数值分析 发表于 2022-9-25 00:202 v0 z( x% E: ?, A% G; u
这个不是这么比的吧。。。/ X! c1 \# D; M  W9 Q- j- e
1 p# N& _& i2 ~5 K* U' e( g
您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。
而加上内循环,光jmp和dec指令就至少多执行了6000个
: h+ E! \8 Z; x$ y0 }% }

4 m% x$ q$ n# O6 E现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果循环这样跑,花不了多少时间。
作者: 数值分析    时间: 2022-9-25 02:06
本帖最后由 数值分析 于 2022-9-25 02:16 编辑 3 Y) _9 @# n1 Q# b* x/ X* R( K& j
沉宝 发表于 2022-9-25 01:48
2 d5 L1 k# F' A6 x. v现在的CPU,可以把判断、jmp和dec指令全部融合进一个µOp(微操作,CPU内部流水线上的执行单位)。如果 ...

9 k; o! E3 Q1 l8 A( h; x% r
" e/ y. f+ d+ C+ I6 Y: Z$ N是的,兄台说的对。
0 O7 _. N, k! G) L4 ~$ Q% z% V
, S! g6 B4 B, {8 \) i其实我想说的是 真正数值计算部分和代码中其他不直接计算的overhead的比值这个事儿。
8 V0 |5 o" ~$ Q- q2 }' A+ S5 Q! Z7 y* _) [* N3 ^6 Q
雷达兄构造测试用例的时候,屏蔽掉了所有计算的部分,使得剩下的都是overhead,这样run time比较的结果就显得好像不合理了。如果把计算加回去,计算部分的run time会dominate,结果就不那么离谱了。因为不好说,所以用指令数对比的方式试图直观地说明这一点。
0 {1 w. L. C: B. H! O& `) r/ m$ a  e' X1 u- j+ H, t$ A
比如说,如果有计算,那么跑六千个循环相对于计算应该用不了多少时间。但是如果一边是什么都不做,另一边是六千个循环,那六千个循环比什么都不做慢几十倍了,就不是那么不合理了。
, P8 R4 [) i) g# c! l+ Z9 Y# F% E" o' t9 [
当然也有可能像兄台说的,是优化参数的问题,但我觉得更多地是测试用例设计的不合理。
作者: 雷达    时间: 2022-9-25 04:47
本帖最后由 雷达 于 2022-9-25 04:49 编辑
; q5 \8 i8 D' N/ i9 \; k+ g
沉宝 发表于 2022-9-25 01:27
: `1 c' t' }7 {9 F你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

- p- D2 j4 @7 y9 f! M" c
& k9 y+ _) Z( Q+ G: D2 S! K% [# J又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。3 r$ t4 F9 c# b  a7 L. Y! {4 E% U
1 u: C; b8 b6 A" ~4 U! U2 h
我已经完全懵了。
作者: 沉宝    时间: 2022-9-25 05:51
雷达 发表于 2022-9-25 04:47' l) b% x* a4 f
又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...
. p( Z3 p% ]$ i+ `5 b3 e
时间差一倍的结果可以接受。6 s2 T* _( t9 |0 d( ?

& L- q$ Z7 Y# ]# h你还是用profile工具看看吧。现在大家都主观瞎猜。
作者: 数值分析    时间: 2022-9-25 14:58
本帖最后由 数值分析 于 2022-9-25 15:38 编辑 / o" {  O0 k/ B: t9 N' P2 p
雷达 发表于 2022-9-25 04:47
) j) d% B4 U. M5 s- y又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差 ...

$ k3 c& d* s5 f
8 L/ J5 r) {9 h4 T4 C$ J
4 `' P; J: \; S
( ~/ N% N! t( y0 B8 B( p( t能不能把这个也贴上来,看看和上一个有什么不同?
作者: 雷达    时间: 2022-9-26 01:30
本帖最后由 雷达 于 2022-9-27 01:17 编辑 . _% ]! e2 J4 c$ |8 @
数值分析 发表于 2022-9-25 14:58$ M  _. }* o/ Q/ f! ?/ L3 v% j
能不能把这个也贴上来,看看和上一个有什么不同?
) W7 L# C1 V4 q4 ~! ^6 E) B0 v
理了理思路,重新做了一个测试。
* @  F1 V" K0 a, J* f# ^) e* H做了两个 vector 和 两个 float *, 都长 100000
( i1 {9 w5 P- O5 C% [* ^5 H外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.) P0 i; ]/ x+ ~
2 v: Y: N) O& W1 X" u7 g
内循环试了4种方法," D5 d! V  z0 Y2 j  A, G
1. 直接调用 vector inner_product 247s % t+ Q7 c) u0 b6 u% Z$ w
2. vector 循环点乘累加 237s5 A0 {8 ?6 C. ]( `& |0 }
3. float * 循环点乘累加 204s
. H% q% n4 M' `' s4. 空循环 100000 次 202s( w* k% t. G4 A7 V

- |. I7 Y7 H/ Z$ R+ x- h1 z不做内循环 200s5 ?3 D8 N0 t; _* F& Z, W
0 g; _. z7 a2 `# ^' W4 l/ p
你昨天说的对,内循环本身占比是很小的,大头在其他处理。
% _  C6 R# {% v2 h3 x7 z另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
2 D8 L6 B! O" ?# J% h7 v( f/ r9 C- `5 F) s8 M/ `9 M
至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
# j- @& B* Y1 P0 Y0 ?
7 p9 t" w% l, ]; z/ w; c% J(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
' x5 T/ I+ m) u: ^, ]: ~) P) {. d7 @" y: r  i7 q3 T: g7 k
        std::vector < float > vec1(N);
2 M+ G4 U5 \" Y" ^( U- X' n        std::vector < float > vec2(N);
2 `3 w" t  y: \1 {$ K0 A        float* b1 = new float[N];
' V# N* W2 k* x" |5 {        float* b2 = new float[N];
& _: V5 A$ ~  ]1 J/ i" P0 H, h( _: |) C2 ]8 x* ~2 z) E/ J; v
        for (int j = 0; j < 6000; j++)  u0 a, B. _: K7 S
        {
4 P+ p# n5 `$ `7 @5 N( c                std::generate(vec1.begin(), vec1.end(), []() {! u+ M" u5 X/ Z+ J; J
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;
+ M3 [% f! f3 }3 x( E" K                        });- H. N. [2 \! `) o4 w! Z

1 G  p! J' S# w4 s+ a; Q                std::generate(vec2.begin(), vec2.end(), []() {5 ^& x2 K) ]7 a  Q: G5 N
                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
9 v* A* X, G0 D& Q) e                        });3 [1 r9 J7 I; a# g- j& V% K

( f$ c7 c& x4 Y5 S4 c; D* y                for (size_t jj = 0; jj < vec1.size(); jj++)" b/ B7 t; J1 n3 \6 w; _
                {, ]( g3 f/ g5 A8 J1 S: x4 {2 b5 w* H
                        b1[jj] = vec1[jj];& `4 |) E5 [7 A
                }, Z$ W# E, a  M. n
. X5 g: l/ [; g+ o% o
                for (size_t jj = 0; jj < vec2.size(); jj++)
& d0 ~, c) ~; \* ]3 u  {                {" _8 t0 {' [$ L' f& v
                        b2[jj] = vec2[jj];
# r* I2 X: q3 @* l; K# K6 K                }
3 y% A* @$ w' F# E- m/ S! v; o, P* \) |
                //Method - 1  N=100000 247s  
1 _" u1 A3 l8 b% `8 T* _# L                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);  T/ T: I  A3 Z8 G
                                % |$ H3 F( S0 d9 X# a2 r
                //Method - 2  N=100000  237s+ K% a; [% {& V
                /*3 {* w3 e6 O6 t" d' b
                for (int jj = 0; jj < N ; jj++), Y4 N" N0 j5 J# w
                {
$ u" u+ u2 I4 w                        fresult += vec1[jj] * vec2[jj];
( P" e% b/ J  [. F4 o5 u                }
4 S; s, N) t+ Q+ u1 R& f0 L                */7 y6 q! a6 B" f
                                
+ G+ B7 e, ^! w/ Y                //Method - 3  N=100000 204s! {5 C. R  {5 v
                /*
4 A% f. S" z# a2 ~5 O. v) F                for (int jj = 0; jj < N; jj++)
: |9 s- E% I/ l; b: L                {3 X% e6 b2 ]! H$ d; l
                        fresult += b1[jj] * b2[jj];- l9 l8 @" f6 t
                }
; Q+ D( ?. K  e  {2 E, b4 l                */& O( E& {: F9 I, ]
/ k& k% F: R2 V+ k% ]# H4 j+ _' w7 S& G3 ?
                //Method - 4   202s
" K5 ]3 N% X# r3 l/ R) h- b                /*
( l" d. H8 r. D; f* q& K0 \                for (int jj = 0; jj < N; jj++)
* ^: |( r1 s! G2 Y8 l                {
3 K) k! Q( k' f. i9 I6 B                          m7 d3 J7 |6 c' G
                }+ r1 q+ V3 d' J# g/ a8 X- \0 K3 |
                */
' n2 J( A! Z5 v* y2 i! R) [                //comment out all methods, N=100000  202s                $ h6 U7 d7 o; j" K
        }
( b+ D- B8 V, O
1 h7 s% A( h- Z' G        delete []b1;
0 ?/ _: E7 e  V( {/ [        delete []b2;
+ S! u1 ?6 ~: ^$ J4 H

作者: 机器猫    时间: 2022-9-27 00:15
瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?3 B  m! \2 Z2 R0 n2 @3 |* Y1 x
8 P' U+ X( g  [, M
你第二个试验里面的j在循环里面又重新定义了啊,你确定真的跑了6000次?5 C5 D# t( z9 D: |

作者: 雷达    时间: 2022-9-27 01:16
机器猫 发表于 2022-9-27 00:15
' Q. V3 g6 J; k0 _) @( F瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
* S6 F0 V& r# E# n* T, h0 u! U* z) X! G* x7 k
你第二个试验里面的j在循环里面又重新定义 ...

$ j0 g' g1 [9 m7 w内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL5 q, X' @( n. k/ L

' S' o4 E- v6 l2 B" D不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
作者: 机器猫    时间: 2022-9-27 02:06
雷达 发表于 2022-9-27 01:162 v) E- L" a/ t& u
内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL, H6 C) H1 z3 ?- E

8 ], o9 Y6 \1 e! c, _不和它 ...

+ m# S- n! P7 q1 H
) o# R7 s. ]; _不过可以试试我说的register变量。前一个试验j是混在一堆其它变量里一起定义的,很有可能是在stack上,这样内存读写会更多,要是再碰上每次都需要加载cache就更慢了。
% W$ _/ w, K$ W5 c  {1 a后面一个是在循环那里定义的,说不定编译器就把它优化成register变量了
作者: opensrc    时间: 2022-9-27 07:25
一个无关问题,为什么爱坛的帖子里在我这里有好些奇怪的东东在里面,是防拷贝措施吗?
作者: 雷声    时间: 2022-9-27 20:29
雷达 发表于 2022-9-24 23:54) r1 F% H3 x1 L7 R/ r0 U6 y# b
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)- r  D  }) U& x( i3 V$ B& B- o3 {
{
2 A  P: I2 o" N! `9 [  g$ d/ O        comp temp, xtimesy;
) e/ |* N: z2 F5 [' s
这个code里面如果Openmp没有被注释掉的话,那么temp那个变量应该是定义在循环里面,否则线程之间会存在争夺写入那个temp的风险。5 O: h4 k. _4 D% v8 p9 D
内层for循环如果没有内部操作的话,编译时应该被优化掉了,和你完全注册掉整个循环是一回事。可能你的编译设置没有打开优化?
) p' L. z: I/ V8 N7 d- KVS社区版没有问题,我工作用的就是社区版,设置正常的话不会比商业版差。以前游说头头用Intel Compiler,他说不想花钱,而且差不了多少,就一直用到现在。
作者: 雷声    时间: 2022-9-27 20:39
雷达 发表于 2022-9-26 01:30; s2 Q9 Y" g* _* [4 s
理了理思路,重新做了一个测试。
( m6 ^. @3 x3 k. O; P# b+ V! v做了两个 vector 和 两个 float *, 都长 100000
8 g- j2 i$ R8 r& U外循环 6000,里面先做随 ...

# G3 ~& c% `- w( }这个时间是从哪里开始算的?/ _( R( H4 @2 t# i
我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, 用了vector那个因为有vector的额外开销,多了几十秒。7 h. E) b* T5 Y9 S6 f
按照两个10万个数字的相关计算的规模来估计的话,两秒都算很长很长了。这个结果真的很奇怪。
作者: 雷达    时间: 2022-9-27 22:41
雷声 发表于 2022-9-27 20:39
# E/ I/ i; X1 z; [& c: W这个时间是从哪里开始算的?
: [4 d# a& `3 v+ V; ?我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
1 ?2 y1 ~: z, {- _/ C' p; r
我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
作者: 四处张望    时间: 2022-9-28 00:12
你这个循环主要的计算时间是那个rand,这个循环本身占用时间微乎其微。& F9 O8 r1 i) J7 I! x
你的空循环,如果是现在的代码,编译器很可能完全不生成对应代码,因为没有任何输出或者修改变量,所以可以看到时间都是202S。你可以认为啥都不干的时间就是那么多。
  m6 u: r4 j3 Z2 x# R+ b) t( c$ n与此对应用数组(指针)花了2S
; {- J7 a5 {& U6 ?( s你用vec1[jj]*vec2[jj]理论上不应该差30多秒,这里很可能是你对vector的操作带来了内存操作,你可以试试把初始化挪出循环然后再比较,理论上vector的随机访问和数组应该几乎没什么区别。
作者: opensrc    时间: 2022-9-28 00:29
雷达 发表于 2022-9-24 23:548 k% |; G. E6 _0 {: t$ h
void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)
7 n+ q7 `$ q+ k8 X$ Y{
& @) D5 g% g, j% @        comp temp, xtimesy;

6 ]0 z! F6 ]& }+ h7 t" G4 k3 e我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
! n+ P( P5 \& A2 L9 u6 D. J# I1 w4 i+ c- E+ V9 C

作者: 雷达    时间: 2022-9-28 00:49
opensrc 发表于 2022-9-28 00:29
- A6 N& H/ _) p7 Z! c1 o. `- Q我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
) v* ~: ?' t: D1 L
4 o9 L/ M" P  m ...
* r& {9 o* N" k2 X4 a1 u+ S( \
你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。3 G- n3 G! W0 ?( p! A( x

3 G; r+ C" E. c# f" {, h雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
作者: 雷达    时间: 2022-9-28 00:56
本帖最后由 雷达 于 2022-9-28 01:09 编辑
+ n# Z9 i' t' f) U1 I* o0 ^0 E2 l+ [9 O) g6 G) L8 |
是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
$ w# ]# `$ z! P  _9 B有空时我会试试 SIMD和并行,看看能提高多少。
6 l. ~- K$ p( n) k, h+ a过去7、8 年没有正经用C++ 写过东西,没有 sense 了 ; X  I! ~, m1 l
谢谢大家的讨论,I learded a lot.  红包已发  / S  S& ]/ G+ i, M  b* e, z

7 `1 T# e5 @; w- B2 k. m4 S" ]" ~

# {1 ?# P1 J! _5 c3 J# W- h0 q# [' A$ x% N( \





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