设为首页收藏本站

爱吱声

 找回密码
 注册
搜索
楼主: 雷达
打印 上一主题 下一主题

[信息技术] C++ 提速的新发现

[复制链接]
  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    跳转到指定楼层
    楼主
     楼主| 发表于 2022-9-24 22:54:26 | 显示全部楼层 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    C++ 比 Octave 慢好多,怎么破?
    , C& Z6 p% C+ l% J" c' r' F  z( y" h5 H+ d$ u5 L* _1 }+ J
    自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。7 L2 Z4 ^; C. a5 ]) _

    ) {% F6 ?/ z$ y3 R% u5 r5 r速度优化问题真的很有意思啊。
    : K+ ?  }. |/ o  a  Z
    # _+ R% L- j( @0 n* B8 v2 j欢迎大家继续讨论

    评分

    参与人数 2爱元 +8 收起 理由
    helloworld + 4
    住在乡下 + 4 涨姿势

    查看全部评分

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    沙发
     楼主| 发表于 2022-9-24 23:54:10 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-24 23:57 编辑
    ( e# ]. k' Q' m8 ~. Q2 d% C
    数值分析 发表于 2022-9-24 23:04
    ! `! U& R2 R; U拉下来?拉多少?
    5 a0 w3 @* F$ `+ @8 S6 A5 F* n把代码贴上来看看?

    5 j7 {& v$ E8 @& V. f! E  E4 R4 h" p" W
    void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB)5 L5 b8 B4 }$ u5 ~
    {
    ' j6 q$ J: c- v3 _: F        comp temp, xtimesy;
    7 q+ F& J; @( a! F9 [/ _        xtimesy.re = 0;
    2 G" T9 j: ~; N7 q$ _        xtimesy.im = 0;; v  ], D' ]$ A9 r% [2 {1 v
            int j0 = lenB - 1;
    2 L3 ~) @" X# m" V2 o& y+ l- w        int    i, j, i1, reali;
    . ~, ]0 s- ~3 Q/ Z3 r        if (lenA % 2 == 1)
    ! y1 X3 h* c- g7 v- T% E: _3 ^                reali = lenA + 1;
    ) L) U! J3 P/ V- ~- ~$ w        else+ I/ w! H, z* S; R/ H' m1 ~
                    reali = lenA;
    : M) \6 d5 u& U" r0 i% Z        reali /= 2;) `: p$ r) q0 z/ i# j- x

    7 ^  a# _0 w" @) Q' p* m3 z& ]        int nconv = reali + lenB;
    + t# G6 R0 A2 p5 M) y6 X        //#pragma omp parallel for
    2 U8 n5 L! ^) s$ I) g        for (i = reali; i < nconv; i++)
    . ]1 S2 Q/ L* n7 }& \7 B$ Z        {
    3 E( e( ^% N. }! c8 u9 h                temp.re = 0;
    6 K$ d$ z3 O' ]- W" S                temp.im = 0;
    4 p+ d) E! C' c+ y5 |$ n                i1 = i;
    1 A" ]- R1 e: F- k5 E4 e. l: Y                for (j = j0; j >= 0; j--)! W; s7 C; I2 h; n( d
                    {) a- \3 G5 {/ p( |
                            /* floating date operation */
    0 `. t( z! m' R, g1 F: ^( i                }

    ' x* O5 s$ W, V        }0 {+ D& d4 U% i$ r  q+ d- c& g, h
    }
    , g4 x2 w5 ]" @3 ~2 U0 ]1 {5 S$ y/ K; B2 E( a4 o4 N4 X' u  _
    xcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
    3 p3 i- Z7 M/ ^5 n4 l
    # a2 z2 g  x' T红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。1 ^1 A6 a, |# J& U# N
    现在call xcorr 100次,耗时78s.) j+ H& i) r! }6 f  ^8 C

    3 e6 N- f0 S$ Z! D$ o; i如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. 1 ^( ~9 O4 e7 M) R
    ( a( T3 v( s3 A/ n0 L
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    板凳
     楼主| 发表于 2022-9-25 00:17:17 | 显示全部楼层
    风雨无阻 发表于 2022-9-24 23:33
    2 A1 k+ |! l) G& i* _- g  vMaybe Debug mode?

    9 ^) R, w% p8 \( k, ~5 _- X5 i- r" W, |: V+ D3 Q: S
    不应该,看我上面的回复。
    2 }3 I. Q6 l( }6 g+ Q' x7 X4 E& B! q* c$ f) C& S
    我更怀疑是 VS 社区版的问题
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    地板
     楼主| 发表于 2022-9-25 00:46:56 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-25 01:09 编辑
    9 |, u  b2 M: z
    数值分析 发表于 2022-9-25 00:203 G2 D: u5 h: ?5 V5 b
    这个不是这么比的吧。。。
    / m/ p, a. k# N3 w1 c& P3 T- Y+ M* L1 P9 A9 Z7 T$ a* C5 {' z8 r
    您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

    " t6 k; ^# \; O4 h+ q  p
      Q5 y1 J' k9 k6 U0 w有道理。
    , K4 V  _; m' }所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。3 E) t6 ]; I* ?" i: c  |9 b

    7 g& C0 b& S; F9 Y7 m1 D* c+ ?4 [$ }我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    5#
     楼主| 发表于 2022-9-25 04:47:43 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-25 04:49 编辑
    % Y9 x3 I( v. I1 b. E/ p
    沉宝 发表于 2022-9-25 01:27
    4 Z" x( K9 x$ W1 L9 q' h, }你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...

    . m/ F  M* }2 o) g# y
    , B% I0 f9 a. a9 o( Q又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
    - _4 g' R# z, N  v( p1 c- p6 ?1 ~! L) ~
    我已经完全懵了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    6#
     楼主| 发表于 2022-9-26 01:30:03 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-27 01:17 编辑
    , ~$ }. g2 V3 q2 u7 [4 ?6 v; b6 r. [
    数值分析 发表于 2022-9-25 14:58
    + x) _4 A7 g! a能不能把这个也贴上来,看看和上一个有什么不同?

    ' {- {/ R1 @1 `% {) Z7 x$ U" c理了理思路,重新做了一个测试。
    9 t- _" d5 Y0 r$ K/ o做了两个 vector 和 两个 float *, 都长 100000
    9 d4 H; s* z2 m) p  k/ V外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.$ w# Q' Q6 G: q, T

    6 x# \7 T8 {9 w/ W* Q内循环试了4种方法,7 L( d/ e' g9 M" W4 z4 y4 I: c
    1. 直接调用 vector inner_product 247s
    5 X8 J: u0 w6 ], r% m2. vector 循环点乘累加 237s* ?' H3 n' Y" U, P2 l$ x
    3. float * 循环点乘累加 204s3 ^6 S8 Q  h0 O" y0 P8 U; H( O6 {
    4. 空循环 100000 次 202s
    " }6 `( ?1 Y: n4 n( _4 @! j( I- b2 F- G, ~; v" Z* }# e) L
    不做内循环 200s3 Y& M6 P; c4 X5 {9 y& I& Y. Q
    ; Y. G  q# z% }
    你昨天说的对,内循环本身占比是很小的,大头在其他处理。7 f3 K2 V, K' }. n% @+ a& [
    另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
    " T. ~% v$ M9 O- Q
    ) @; T6 i. s6 u' ~至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)9 G7 |1 @5 e. D0 W

    ; B& @* H) d2 _9 A) V& {(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)( ~: Q, R( z  }

      N5 B9 ~+ T# o
            std::vector < float > vec1(N);3 h+ n& m' h) i7 L  e# `5 Z
            std::vector < float > vec2(N);
    * b! F- i4 ^+ c5 `# c        float* b1 = new float[N];
    # t3 p" g1 G9 Q) w/ M7 e! [        float* b2 = new float[N];% x, Y  D8 b, a8 w7 c
    6 ?2 s( Q5 ?' q* a
            for (int j = 0; j < 6000; j++)
    , C7 P- [' T3 A        {+ s/ N7 V# z# f; X
                    std::generate(vec1.begin(), vec1.end(), []() {4 j! o4 Q! n) d: }8 ?! m  |# M
                            return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;5 m# |  Y" b+ Z5 r5 e( `
                            });' J9 Y  v3 L8 |8 O- r% G

    * P1 a8 M! B6 v- _8 r, D& e7 Z                std::generate(vec2.begin(), vec2.end(), []() {
    : Y* K  _! \, h" b1 a                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;
    5 O' U( P) c9 g( B, k3 [) a0 g! Z                        });
    ' Q) ~7 e* j4 M; c! S. h) i9 o
    % J; @( ?4 k0 S% d. |3 c) {                for (size_t jj = 0; jj < vec1.size(); jj++)4 d3 j, [0 j1 b$ u' o8 G
                    {
    2 x2 ~8 Z7 A$ L                        b1[jj] = vec1[jj];3 }; N) M" j& j, J9 @3 ?2 T8 L1 |; M
                    }+ ^6 h" ]; H/ X9 b) V
    , S, }$ r0 ^; v% ?: p  Q
                    for (size_t jj = 0; jj < vec2.size(); jj++)
    : f' I; d8 F& j( d                {
    3 c; D/ I9 k" @# x. v( H, }8 h: p! [+ @                        b2[jj] = vec2[jj];
    8 x; p, _. u3 }+ j3 X$ R6 ^                }4 \* q6 C: V% r- p' d$ B
    2 A/ _4 f  t, J/ \  l3 U
                    //Method - 1  N=100000 247s  
    % n$ h* K6 e5 }3 ]: ~; C9 l                //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);! \: @' c1 s; B* F6 r
                                    ! j. `% j. ^' r' b$ L% I6 x  F7 ~
                    //Method - 2  N=100000  237s! j$ c( O6 s% ^: R  w- f$ V
                    /*
    1 k0 N; j0 N# o9 n. k9 V4 V; y                for (int jj = 0; jj < N ; jj++)  X6 O- u* ~5 }9 f/ J5 L0 P7 g0 T
                    {( e6 S7 f0 d1 A
                            fresult += vec1[jj] * vec2[jj];
    ! w& ~9 ~( o" c, ]: v. y: j                }
    , K' B2 D5 s/ f                */, S. v& m" b0 I' H
                                    7 r% B/ x, D. X0 E1 h
                    //Method - 3  N=100000 204s7 n0 J& _! P8 s% d; @
                    /*
    * j6 O( e) u  x$ g                for (int jj = 0; jj < N; jj++)
    + `2 X9 b+ K' b, t" u                {3 ~) B- S" ?3 {. Q) j/ z/ \0 M
                            fresult += b1[jj] * b2[jj];0 p% H  w. z+ v+ \# W6 \8 ]
                    }5 A5 C: a; O$ g4 \  b
                    */) b) D) g% o. E$ L
    ) V' o3 N; l3 v: p
                    //Method - 4   202s/ p- T1 ~2 \* }' E3 k
                    /*
    7 R) U  s& ?$ T! Q                for (int jj = 0; jj < N; jj++)6 L: g) W  A+ I  S' }1 r5 h
                    {8 t# k+ N' b7 W4 @
                            # ]; d+ m" w' V
                    }
    ) k6 e+ S4 G# m9 B. s  j( n6 i( b                */" d# R4 ^# i" k- ?3 k0 j) g
                    //comment out all methods, N=100000  202s               
    4 G# A+ a. |# q5 U        }; t0 S  n2 d- s$ ]- P
    : A4 j9 l4 R9 o# T
            delete []b1;
    # ^, [% i, D) ~9 N" W" \        delete []b2;

    ' s  i' ]+ f& Q, N
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    7#
     楼主| 发表于 2022-9-27 01:16:03 | 显示全部楼层
    机器猫 发表于 2022-9-27 00:15
    ; ]3 U. g+ z6 x; g! m" k瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?
    ! t) \! b: s. b( a6 a
    ' Z- E6 E& R% m$ x  K2 D你第二个试验里面的j在循环里面又重新定义 ...
    2 I! A8 w2 {6 @" n2 z* ^
    内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL$ f: J7 A% @$ Y8 _

    # {! G4 D6 i. k) D- |不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    8#
     楼主| 发表于 2022-9-27 22:41:56 | 显示全部楼层
    雷声 发表于 2022-9-27 20:39/ b  u' D, q3 D+ x
    这个时间是从哪里开始算的?! R7 U* _. e$ I8 ^
    我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
    9 I5 a5 }  m! K# d/ Z6 n
    我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    9#
     楼主| 发表于 2022-9-28 00:49:59 | 显示全部楼层
    opensrc 发表于 2022-9-28 00:293 ~& j5 {2 B% T% E- X+ w. s) n0 r; @4 i
    我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗2 M) Z( [9 W7 ~1 o
    0 c1 {2 v- m0 M/ {
    ...

    - m" P3 I8 }0 M你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。6 _' r* [+ v4 J/ \+ g- R& v- o7 M
    1 @; a# l' u6 G
    雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-29 05:09
  • 签到天数: 1180 天

    [LV.10]大乘

    10#
     楼主| 发表于 2022-9-28 00:56:28 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-28 01:09 编辑 6 }; C3 Z* T3 g3 m  p

    2 J$ @; C( I& y& X9 B" \! x& s是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。8 x) N3 o  P: w
    有空时我会试试 SIMD和并行,看看能提高多少。
    ' X8 O& R3 ^* K! u过去7、8 年没有正经用C++ 写过东西,没有 sense 了
    9 U# h, I* X! g. e! }谢谢大家的讨论,I learded a lot.  红包已发  
      o; s) {; {3 Z5 V1 f8 h( ?; \8 \' u0 C, U6 ~; {- W
    " l9 E% H7 m4 q

    - \+ H1 l. A9 Y9 G: `" z
    9 a  Y& e; A* p
    回复 支持 反对

    使用道具 举报

    手机版|小黑屋|Archiver|网站错误报告|爱吱声   

    GMT+8, 2024-5-27 14:44 , Processed in 0.046605 second(s), 20 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表