设为首页收藏本站

爱吱声

 找回密码
 注册
搜索
查看: 3197|回复: 25
打印 上一主题 下一主题

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

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

    [LV.10]大乘

    跳转到指定楼层
    楼主
     楼主| 发表于 2022-9-24 22:54:26 | 显示全部楼层 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    C++ 比 Octave 慢好多,怎么破?# o, {' R# M2 |3 P$ o1 _) x: r2 G
    - i7 a$ O  S: X) R. g8 I
    自相关两层循环,内层循环涉及浮点数计算,试验了一下把内层循环内部全都 comment out 只留个壳子,  但空的内层循环本身就把速度拉下来了,看来问题并不在浮点计算。4 B( i+ r1 i  p

    / Z5 m4 A7 i3 r5 i速度优化问题真的很有意思啊。
    : X( l3 `+ i% t  h$ A; f- B
    0 g+ ~. A. C: V' Q# J- K欢迎大家继续讨论

    评分

    参与人数 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 编辑
    % Y- p+ L$ z* D, T* B
    数值分析 发表于 2022-9-24 23:04
    ) y/ W- n& g" ~& _9 R8 H5 M( H拉下来?拉多少?
    ! [' f2 |# v4 ?7 E- w6 Z把代码贴上来看看?
    6 u. v* M# u) `* S$ {# i) l
    % Y3 D, }( e, j" k5 U
    void xcorr(comp* outcomp, comp* A, int lenA, comp* B, int lenB): I6 H6 X1 z9 C7 f8 h& _" q
    {3 u8 r) }! c# C$ ], ]( H% `
            comp temp, xtimesy;
    7 r/ m4 m# _' h7 W* H        xtimesy.re = 0;
    / T: o$ r3 l9 ]% j0 m        xtimesy.im = 0;
    2 M1 m& m0 |0 {, O! k' O# A' M3 j. T        int j0 = lenB - 1;
    . w& |3 e4 `5 r5 G        int    i, j, i1, reali;
    9 a* v$ _# e1 o        if (lenA % 2 == 1)  r/ n$ x( e- L& _
                    reali = lenA + 1;8 }  g/ R. _! c6 a' u
            else
    , T. l; j: _+ }* M                reali = lenA;  M, M6 f2 x' C" v/ v5 F( K
            reali /= 2;: Z; I' L/ v/ C8 V5 C

    # d0 K) D% L. ^# Z+ H, V/ v        int nconv = reali + lenB;7 c/ H) B$ k, }( O. u4 ]- i
            //#pragma omp parallel for
    0 \! @) [- I& c* r. f! v6 K        for (i = reali; i < nconv; i++)6 B4 E. N0 @0 I" Y. Z, c
            {8 z5 E/ V9 D( }" V7 S
                    temp.re = 0;
    ' n; a5 @# [, l4 P/ n                temp.im = 0;. K5 N- }% M+ J' @5 ~
                    i1 = i;
    : U4 e  H% _& r                for (j = j0; j >= 0; j--)
    ( a6 T' v' `! A3 W; _4 }. F+ w" z- p; s                {, D* q. Z" O$ |
                            /* floating date operation */0 O1 `5 r( ^: Q. g# N- K
                    }
    7 x" P$ H: j) ]. z0 I
            }
    $ g( g( ]8 Y9 s- n2 l" l}
    & Q- a& Y7 v/ A8 G
    ' U1 K$ Q- t4 Z3 K! cxcorr函数代码如上,comp是复数struct, 做过长度为11、19两个矢量的测试,和octave结果完全一样
    1 J8 L/ J" e7 L' H: p% b* p" i7 q7 X- n  F) i' V
    红色部分是内循环,现在其内部操作都comment out 了, j0大概是 6000。, L9 F4 Q0 Y+ q1 ~0 Z( y
    现在call xcorr 100次,耗时78s.
    % s; U  [9 @' W
    ( T1 }) ^' o/ I9 L3 i2 ~3 V如果把红色部分内循环本身完全comment out, call xcorr 1000次,耗时 <1s. + N- a: E, ~3 Q+ M- Z
    * F/ A; |7 M$ e" s8 n; B9 W
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    板凳
     楼主| 发表于 2022-9-25 00:17:17 | 显示全部楼层
    风雨无阻 发表于 2022-9-24 23:333 O* q, J2 n. e# Y
    Maybe Debug mode?

    . j" P# n# F. [+ y. `8 _8 n* J, X5 F# b# [
    不应该,看我上面的回复。1 j0 o  Z) o# V. q

    ; u# B0 G, s& ^5 ?8 H& w6 Z我更怀疑是 VS 社区版的问题
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    地板
     楼主| 发表于 2022-9-25 00:46:56 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-25 01:09 编辑 ! H2 Z3 ]/ b. |& m7 b& q
    数值分析 发表于 2022-9-25 00:20# P: T, Z% e6 M+ }3 A2 @
    这个不是这么比的吧。。。& o  w. a' F! B/ O- b1 N5 ?
      ]" }1 s; @8 v3 w9 U  T
    您这个函数,不带内循环的话,汇编完总共操作也没几个(不到100个)。

    $ Z0 d8 f2 `3 q
    9 N8 I9 q- A; }9 C- C有道理。0 u) _. |1 O3 S$ a4 A) P
    所以存在内循环速度就上不去,把内循环取消,改成两个向量直接点乘再求和应该就会好得多,记得 numeric 库里有算向量内积的,我回头试试。/ A6 Z) Y0 a; P

    # ?5 t% i/ |% y& W/ y我先尝试尽量用标准库,一个小程序,不想搞得太复杂。多谢了
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    5#
     楼主| 发表于 2022-9-25 04:47:43 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-25 04:49 编辑   M: y- ?1 N; g; a: |+ E" j7 P* }
    沉宝 发表于 2022-9-25 01:27$ X1 y: D5 L. r( Z
    你两个试验之间就差了一个空循环, call 1000次按理不会有秒级差异,可能还是编译器优化的问题。举个例子 ...
    9 k/ |+ B. ^- O! v& H1 l) F+ Y, F
    0 a4 ?9 \( s( M# i$ A) W3 ]4 ]
    又写了个小实验,没有调用子函数,双层循环,外层6千次,内循环30万次空转,有或没有空转内循环,时间差一倍,我上面这个差的太多了。
    6 t9 f7 }- X+ g6 U
    . [1 @5 K' K, k) Q5 R3 B我已经完全懵了。
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    6#
     楼主| 发表于 2022-9-26 01:30:03 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-27 01:17 编辑
    ; Z" `8 U2 O. h3 z: ~4 A
    数值分析 发表于 2022-9-25 14:58
    $ s5 i5 \0 _( L5 X2 B. W4 f能不能把这个也贴上来,看看和上一个有什么不同?
    & _) W" T: x" D
    理了理思路,重新做了一个测试。
    " |$ h6 |$ b: g5 x- E做了两个 vector 和 两个 float *, 都长 100000' [# G- X0 d. H, [
    外循环 6000,里面先做随机数生成,模拟真实环境,避免数据的 cache.0 }# F9 a1 f. H/ s

      N0 _- ?; L  e' G( @) k7 O1 u& z内循环试了4种方法,; D" y) u$ y3 J% |9 i9 n/ R
    1. 直接调用 vector inner_product 247s
    $ x6 {; H5 K/ v2. vector 循环点乘累加 237s
    ) V% k% M' x2 U9 H2 M5 K0 r! X3. float * 循环点乘累加 204s2 L% Q# ?; k- {' A% e- ~6 S
    4. 空循环 100000 次 202s
    * d% T" `" X+ x: G$ u4 |; G4 n9 Z. }" j0 o6 g0 x1 d2 j
    不做内循环 200s
    1 S) h9 t5 L# N7 X. g6 u9 w  B0 k
    4 T% ^- I, E! R, f7 e/ [你昨天说的对,内循环本身占比是很小的,大头在其他处理。
    " B7 B1 W' v; V$ e另外可以看到, float * 循环点乘累加 并不差,比用vector 还更快。
    ; G; g$ j& H0 }$ M1 t
    ; \$ Q/ g( T' K: A至于我那个原始程序,还有一些疑问,见5楼,其他都不变仅仅是有无空的内循环就有很大不同,这是不对的,也许有一些其他缺陷我没有看到。(也许可以改成 while 试试)
    % T6 D6 U. x- n3 ]/ ]9 ~
    2 b. ?- j! h8 U; q% l9 w(为什么下面我贴的  b1 加 方括号里的 i , 显示出来却是 b1 ?方括号 i 消失了。 LOL . 改成  jj 好了,原来 方括号里的 i 是斜体标志  LOL)
    4 m2 I: c/ L. B. k- E" O: ^4 ?' b
            std::vector < float > vec1(N);8 Y: J+ p5 q. O- ~* q3 B( L
            std::vector < float > vec2(N);2 k( s% A9 K3 x4 g" _$ Z
            float* b1 = new float[N];5 n; e, @: r' z' A
            float* b2 = new float[N];
    9 {0 o  }3 B/ {8 @. y5 I. O; d* x5 Q" o  |" N6 `% r( e7 P
            for (int j = 0; j < 6000; j++)/ ^  d5 v* W( m( k, r7 s# f; r
            {
    ) Q: J; |. g2 h4 u                std::generate(vec1.begin(), vec1.end(), []() {% N! x/ H, n3 z9 a) b
                            return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 23.23));;5 O% G8 l; K- ]1 W; p0 @$ {
                            });+ J" |) C! K7 g0 ^

    * s" W* @8 l. n- k                std::generate(vec2.begin(), vec2.end(), []() {
    7 r) E3 B$ s9 m                        return static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 24.31));;  G: x, e8 @( v
                            });+ _. C' F$ a! D9 F2 f
    4 A5 W! i* N& k" p) G0 I
                    for (size_t jj = 0; jj < vec1.size(); jj++)
    ' t& W8 S7 r, C* m5 P                {& d; B, }* O7 B4 A$ Z7 x
                            b1[jj] = vec1[jj];
    * H+ q+ ~4 F3 Y: O/ y* T% P# P                }& K( D& a% ~. K
    2 X, I/ T* e* G+ R8 v7 P; L9 q
                    for (size_t jj = 0; jj < vec2.size(); jj++)8 X/ Z% T, N0 K" G2 ]
                    {) d/ `/ w" u5 u' r( ]9 s7 U% T
                            b2[jj] = vec2[jj];
    # V& R$ W( ?( g. A0 w( R4 V8 s4 e                }. p( V$ |' [( a$ F) e

    9 i' X0 }; u- D- ?                //Method - 1  N=100000 247s  $ Z% r1 u5 v* M) a# |
                    //fresult = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
    ! D6 _! F% T8 M" E6 n0 y                                : ~0 L5 W( D: ~# ?6 d
                    //Method - 2  N=100000  237s
    ( }* f. g8 L! K) f* w3 m                /*
    * W- P% g* X2 A* b* z' ?/ `& g9 q                for (int jj = 0; jj < N ; jj++)
    $ }( Y% q, `( z% b& f3 h                {
    ' g# x5 [3 d- E                        fresult += vec1[jj] * vec2[jj];* L$ D5 N1 M" W6 W
                    }/ t! O% Y+ w$ t6 q
                    */& J5 k% [! H4 z' b
                                    : Y; q/ c: _0 q  q$ T1 D7 W2 I
                    //Method - 3  N=100000 204s/ ]4 G5 y* |7 \4 y% G
                    /*$ m1 u) t/ S& F! o; [
                    for (int jj = 0; jj < N; jj++)9 s! g  t7 W( x4 }2 U# `
                    {
    ( \. _3 e8 F5 m% U7 \                        fresult += b1[jj] * b2[jj];
    5 _( ?# ~- v* u' ?) s                }
    * [8 b4 M- N2 Z1 e                */
    ( }& H' D5 w$ K: i/ R% g9 ~7 C# d$ e4 g3 C! g$ X" H
                    //Method - 4   202s
    * G" h# u7 J7 |- K2 ]4 r1 R2 E                /*4 G) C0 K* s( z% J5 m2 S
                    for (int jj = 0; jj < N; jj++)
    6 U  z. T' U2 _) ]& j+ @2 d- t5 n                {# C) `% U4 d* ?# Q8 t0 U7 c) d
                            - n! _& S; _$ n  Q$ j; T  ~5 h
                    }/ C; g2 H8 N4 C/ ~9 f* j
                    */* @, N& Q% y7 J/ x$ N' E( O3 T7 C
                    //comment out all methods, N=100000  202s               
    + Z/ r- a. @" `& b9 Q. K        }
    , K; `- Y; N, }8 T" r
    4 [! {+ z9 ^6 q        delete []b1;* d1 P! `) p9 g' M" b& N
            delete []b2;

    . y. ?3 @: ?7 H! o, N) `( q
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    7#
     楼主| 发表于 2022-9-27 01:16:03 | 显示全部楼层
    机器猫 发表于 2022-9-27 00:151 v2 o5 G7 ?3 W% h
    瞎猜一下啊。把第一个的那个j定义成register变量会不会有不同?- \$ s- l& S$ Z9 @5 G

    ! C: O0 K1 X5 K4 i0 O% B- o你第二个试验里面的j在循环里面又重新定义 ...
    ! i! B- S/ x5 m$ `5 K  Z
    内循环里面的 j 实际是 i, 为了规避爱坛显示的冲突帖子里临时改成了j, 现在是 jj 了。好累 、LOL. a8 e7 }' I# R) ^9 P' Q& ?

    / p5 A' V8 \. n5 Q* k, O' q7 Q" j不和它较劲了,瞎耽误工夫,我已经转到 ubuntu, 也准备顺便试试 avx2 向量化。
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    8#
     楼主| 发表于 2022-9-27 22:41:56 | 显示全部楼层
    雷声 发表于 2022-9-27 20:39& j7 p9 w* m1 r7 s# L5 ^
    这个时间是从哪里开始算的?6 K' N( K& }; h% O3 O
    我怀疑这个200多秒里面有200秒花在产生随机数上了,真正计算大概只用了2秒, ...
    , B/ ~% _1 e, M
    我不管它了,回头 linux 下换g++重新编译,顺便加上你们建议的向量化。
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    9#
     楼主| 发表于 2022-9-28 00:49:59 | 显示全部楼层
    opensrc 发表于 2022-9-28 00:29( S, b+ ^4 X" L7 [; T* ?5 }
    我有些迷糊,这样的code,难道不就应该时间差很多吗?也做了个简单的实验,你看看我做的有错吗
    6 E1 A# d# m$ t+ R# C9 n/ ^% k. B# V. z$ _3 S
    ...
    : @. s. K7 k" X' i: a5 [+ I) d5 C
    你是对的,是我搞错了。确实没有优化的情况下,空循环如果次数够长本来就应该耗时较大。我搞错的原因是在不自觉得与 octave 比较,而实际上 octave 是优化过的,和是不是空循环没关系,这种不同条件的比较是没意义的。
    ) \0 v6 Z5 S* P* z' i0 Q0 s& O2 \0 t! L- s6 K0 c
    雷声网友说的也对,空循环应该被编译器优化掉,我的编译器设置有问题。
    回复 支持 反对

    使用道具 举报

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

    [LV.10]大乘

    10#
     楼主| 发表于 2022-9-28 00:56:28 | 显示全部楼层
    本帖最后由 雷达 于 2022-9-28 01:09 编辑
    ! G# d% s' J2 t0 Y% F. B$ l% L0 h3 Q- m4 P
    是我自己的理解有误,没有优化的情况下,空循环如果次数够长本来就应该耗时较大。
    * L) |# t' `/ |, X6 `有空时我会试试 SIMD和并行,看看能提高多少。
    % r, r3 `& p6 u. N: D: d( o过去7、8 年没有正经用C++ 写过东西,没有 sense 了
    . x1 j1 m, V6 v5 X- ~谢谢大家的讨论,I learded a lot.  红包已发  
    - j0 g1 U1 `5 X
    5 I. r3 W7 X# A6 m6 q- V: ]
    ! |' s( j1 U1 \" O" {3 A; C' E' ?$ y! ]
    - `+ m  r8 ^! `% ~7 `
    回复 支持 反对

    使用道具 举报

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

    GMT+8, 2024-6-1 20:17 , Processed in 0.041212 second(s), 20 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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