设为首页收藏本站

爱吱声

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

[信息技术] C++ 比 Octave 慢好多,怎么破?

[复制链接]
  • TA的每日心情
    擦汗
    2024-12-25 23:22
  • 签到天数: 1182 天

    [LV.10]大乘

    跳转到指定楼层
    楼主
     楼主| 发表于 2022-9-23 06:27:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 雷达 于 2022-9-23 06:29 编辑
    4 v" B8 Z" e8 w4 `5 X$ i+ q: Y& `& N; y& Z
    做一个数字信号处理的小算法,需要算互相关。3 y8 r) S9 i+ r8 d; F, a
    先用 Octave (兼容matlab 那个东东) 做了一下,感觉慢,走通后就用C++ 重写,结果比 Octave 还慢,目测能慢10倍,很不科学啊。
    ( U9 w: G+ N% Y* @0 {" {% T/ M: A9 X
    Octave的互相关有现成函数 xcorr,  C++ 需要自己写。互相关是一个一维矢量和一个二维数组里的矢量依次做。矢量里是复数数据,没有用 STL,自己做了个  Re/Im 的struct,其实就是两个四字节 float 。% T% H1 W' [1 ]5 l- A
    互相关的最基本运算是两个复数的乘法,就是四次 float 乘法再相加,所以本质上影响速度的应该就是 float 乘法和加法。
    ' r$ Y' Y& d9 C# V* u3 U7 U( j1 U5 w' h7 B7 v6 ]
    C++ 用的是VS 社区版,估计编译器不给力,但也不至于差这么多啊。* ?- y2 I" y% e

    " R) v# x7 c) w! F! j7 Y5 m高手们给分析分析,  多谢了。
    & S  E3 U9 ^2 b+ G- X$ C

    评分

    参与人数 3爱元 +18 收起 理由
    helloworld + 4
    MacArthur + 4
    indy + 10 伙呆了

    查看全部评分

    该用户从未签到

    沙发
    发表于 2022-9-23 07:02:18 | 只看该作者
    互相关这种是最适合矢量化的,Octave应该是用SIMD 或者CUDA写了核心的计算部分。所以比没有优化的快很多。我差不多20年前做过类似的二维相关处理,优化过的比老师自己写的快了三四十倍,实验室的小崽子们怨声载道。因为本来等处理完一次数据需要差不多六七个小时,正好打游戏。优化完了之后不到二十分钟就好了。啥也干不了。
    & [2 ]1 z  x* L. `1 r( z9 _* R1 b你想省事的话用Intel的IPP库,里面有现成的高度优化的互相关函数。或者用CUDA自己写一个。
    ! D- D; R/ @) i7 y, A你做信号处理很熟的话,这个还可以用FFT来做。应该会更快一些。九十年代很多人这么处理,主要是那时候CPU实在太慢。现在基本用不着了。而且FFT前后处理比较麻烦,加窗什么的。

    点评

    给力: 5.0 油菜: 5.0
    涨姿势: 5.0
    给力: 5 涨姿势: 5
      发表于 2022-9-23 22:31
    油菜: 5 给力: 5 涨姿势: 5
      发表于 2022-9-23 18:40
    油菜: 5 涨姿势: 5
      发表于 2022-9-23 11:16
    给力: 5
      发表于 2022-9-23 09:14

    评分

    参与人数 2爱元 +18 收起 理由
    雨楼 + 8
    colin1992 + 10

    查看全部评分

    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-12-25 23:22
  • 签到天数: 1182 天

    [LV.10]大乘

    板凳
     楼主| 发表于 2022-9-23 08:13:54 | 只看该作者
    本帖最后由 雷达 于 2022-9-23 08:15 编辑 3 U3 U0 \  l) B0 B# U2 V$ l
    雷声 发表于 2022-9-23 07:02
    + e: O2 r9 b# L- F, @  Y互相关这种是最适合矢量化的,Octave应该是用SIMD 或者CUDA写了核心的计算部分。所以比没有优化的快很多。 ...
    * S$ A& r1 S/ a+ e) U) s: A

    5 }& E4 e' U, r  D3 w: H- ]8 S嗯, 我就是觉得 FFT 反而麻烦,互相关代码本身倒真没有几行。那看来就用 octave 就好了,没必要再用C++重写了。- T' H, H0 c: W2 _
    另外,我现在就是用指针数组,如果用 STL 的Vector 会不会更快一些?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-4-20 05:43
  • 签到天数: 300 天

    [LV.8]合体

    地板
    发表于 2022-9-23 09:18:16 | 只看该作者
    Octave/Matlab内部对数值计算做了很多并行和优化。内核甚至是用Fortran写的。你用C++重写,没有做并行优化,真未必比他们的性能好。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-8-28 01:10
  • 签到天数: 1748 天

    [LV.Master]无

    5#
    发表于 2022-9-23 09:55:04 | 只看该作者
    Matlab不是浪得虚名的,要打败它还是要下点功夫才行
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-12-25 23:22
  • 签到天数: 1182 天

    [LV.10]大乘

    6#
     楼主| 发表于 2022-9-23 11:00:38 | 只看该作者
    本帖最后由 雷达 于 2022-9-23 11:10 编辑 4 w4 P* {* M* I9 {& D
    5 s% T, Z, g7 v; N+ U3 G+ `
    研究了一下,似乎可以用预处理指令对浮点运算做一些优化。这个问题比我最初想象的要复杂得多
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 3505 天

    [LV.Master]无

    7#
    发表于 2022-9-23 11:18:11 | 只看该作者
    汇编快!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 07:08
  • 签到天数: 1930 天

    [LV.Master]无

    8#
    发表于 2022-9-23 11:34:49 | 只看该作者
    本帖最后由 数值分析 于 2022-9-23 11:48 编辑 3 K( M6 R9 H3 [$ t( z
    1 D2 `# J+ _. Y( w% ?
    C++ code 用的是普通乘法?换成sse/avx向量乘法试试?) T- F2 |2 c6 b" f
    并且是单线程的?加个openmp并行试试3 f, v* O. j5 D- K2 _
    或者调用mkl 库的互相关函数试试, e2 K. ~; \- U8 ?2 W

    点评

    +1: 5.0 给力: 5.0
    涨姿势: 5.0
    给力: 5 涨姿势: 5
      发表于 2022-9-23 22:32
    +1: 5
      发表于 2022-9-23 11:55
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2024-2-11 13:31
  • 签到天数: 141 天

    [LV.7]分神

    9#
    发表于 2022-9-23 11:43:35 | 只看该作者
    马鹿 发表于 2022-9-23 11:18
    3 F( d" z" W  X8 i( x: H8 i. u汇编快!

    3 r! c- T: N5 k0 s, V0 X, Q) T. [% }这种问题的优化, 在语言层面没太大意义, c++和汇编没什么本质区别.8 T$ @% }6 w. @4 m3 ~

    " \! ^3 _' u0 k" E9 u! O& S最好还是用高性能的计算库, 比如intel的ipp,或者看看gpu方面有没有类似的库.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    10#
    发表于 2022-9-23 12:59:58 | 只看该作者
    涉及矩阵的用blas
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2020-1-3 00:51
  • 签到天数: 71 天

    [LV.6]出窍

    11#
    发表于 2022-9-23 14:05:11 | 只看该作者
    实际使用中要考虑综合成本/时间。比如用octave /Python 解决起来简单。自己另起炉灶麻烦些。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    12#
    发表于 2022-9-23 15:48:12 | 只看该作者
    雷达 发表于 2022-9-23 08:13
    $ x/ [0 h8 O- V5 c$ J嗯, 我就是觉得 FFT 反而麻烦,互相关代码本身倒真没有几行。那看来就用 octave 就好了,没必要再用C++ ...
    1 t; Q) f# }$ _
    STL对性能优化没什么帮助,只是写起来比较安全而已。  _! w- T; i: P- N. a
    下面数值分析回答的是对的,要么用avx自己写,要么就凑合用octave得了。
    ) U1 M/ B1 m9 {# a! U买个Ipp库虽然不贵,但是还是要几百刀的吧?
    0 p0 H0 x' i: p. }+ m
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    昨天 17:41
  • 签到天数: 1640 天

    [LV.Master]无

    13#
    发表于 2022-9-23 16:05:15 | 只看该作者
    矩阵最简单用eigen,然后enable  avx2以上
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 3505 天

    [LV.Master]无

    14#
    发表于 2022-9-23 20:24:06 | 只看该作者
    mark 发表于 2022-9-22 22:43
    8 D5 T" S( B1 P: B" c这种问题的优化, 在语言层面没太大意义, c++和汇编没什么本质区别.  a  ~( z% }0 s' X+ z3 i

    " b" s0 @% E- C: Q/ F$ @最好还是用高性能的计算库, 比如inte ...

    ( P! W  C* |5 X  k6 G9 y我不是it的,说汇编是起哄呢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    15#
    发表于 2022-9-23 20:53:40 | 只看该作者
    雷声 发表于 2022-9-23 15:48  l7 \; P# k  l6 E1 N& x  `# U
    STL对性能优化没什么帮助,只是写起来比较安全而已。
    % t9 u5 Z4 L9 ]下面数值分析回答的是对的,要么用avx自己写,要么 ...

    + L# z% R3 ^& ]$ G* p/ X. B. W你觉得在用AVX自己写与用GPU加速的Octave之间,谁有可能性能上超出?(基于中等价位的硬件水平)
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 07:08
  • 签到天数: 1930 天

    [LV.Master]无

    16#
    发表于 2022-9-23 21:37:24 | 只看该作者
    本帖最后由 数值分析 于 2022-9-23 23:50 编辑 " V9 Z; a% C  T# q1 Q; A
    沉宝 发表于 2022-9-23 20:53# h) [$ t4 J  X# m& V
    你觉得在用AVX自己写与用GPU加速的Octave之间,谁有可能性能上超出?(基于中等价位的硬件水平) ...
    * P/ c9 L$ A; o3 n7 Z$ s

    % `: N4 p+ y+ h必然是GPU啊,10来个核心对上千个计算单元。。。" q2 w: a1 q* t

    " e2 H5 ?7 k" |* C8 K& B+ H有道是 双拳难敌四手 一虎不如群狼
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    17#
    发表于 2022-9-26 18:34:55 | 只看该作者
    先用性能探查器看下热点在哪里,用前面坛友们的方法针对性优化下,满足了应用需求就收手(心中牢记那句箴言:又不是不能用!
    0 t2 ~# l8 i( j# Q1 G6 n, @, I' D  c& M. |- }3 r6 t
    不知道vs的社区版带不带性能探查器,不行的话用pro/ent试用几天应该是不违规的,实在不行把C++编译到Linux下,那perf工具可就多了去了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-2-8 10:08
  • 签到天数: 2 天

    [LV.1]炼气

    18#
    发表于 2022-9-26 23:30:40 | 只看该作者
    mark 发表于 2022-9-23 11:43
    4 x2 X7 Q  ]6 o1 J3 c4 U; r6 y0 x这种问题的优化, 在语言层面没太大意义, c++和汇编没什么本质区别.
    ) p' h8 N; Q2 ]2 e8 O+ [1 f; k
      d. b7 x( j+ a7 J最好还是用高性能的计算库, 比如inte ...

    ( T7 E' N& b" W2 d+ b7 H* \" I; z区别还是很大的。编译器的优化还到不了那种程度。
    " Y2 U4 w3 K5 M1 d- |你说的那些“高性能的计算库”很多估计都是专门的人用汇编手工优化出来的。那个得对要优化的系统非常熟悉的人来干,打个比方那条指令用在哪个地方会导致cache需要加载,这些都必须考虑到9 ^8 T9 Q6 O! s* L7 v7 Z2 W
    : l0 ?' ?" z( K' @" W4 r
    当然对于调用这些库的代码来说,一般C和汇编区别不大
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    19#
    发表于 2022-10-2 01:38:20 | 只看该作者
    现在进展怎么样了?5 I: k! b2 y+ U9 ?$ p4 x
    : l/ C7 N* U! n  n2 O
    想了解一下你问题的规模:
    ) f. p2 O) D( @, c3 d5 w3 M1) 你说互相关是一个一维矢量和一个二维数组里的矢量依次做,那么这个二维数组有什么特殊意义吗?需要对所有维度按列操作并返回一个矩阵,还是就是简单的一对一算过去?换一句话,本质上要的是一个1-维互相关算法,还是N-维互相关算法。
    : {0 z$ I+ _. I6 G( W2) 矢量和一个二维数组的长度大概是多少?
    2 j4 o) _3 q" U3 L. X4 `) n3) Octave 大约跑了多长时间,你心里期望的速度大约是多少?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-12-25 23:22
  • 签到天数: 1182 天

    [LV.10]大乘

    20#
     楼主| 发表于 2022-10-2 03:04:55 | 只看该作者
    本帖最后由 雷达 于 2022-10-2 03:06 编辑
    - p( ?1 Q3 Y8 b; _1 p
    沉宝 发表于 2022-10-2 01:38# D) ?4 g" F3 {4 D: B  ^
    现在进展怎么样了?, L3 ~+ D* |+ C

    ; _. o" u! |. U/ c- k" n想了解一下你问题的规模:
    - |1 c; c" o" w$ t; O  k4 K
    ! g) H9 n% u3 y9 u( @3 r
    多谢关注。
    % [# K) o4 l! t# T7 q规模还比较大,一个至少3万*3万的二维浮点复数矩阵,用一个4000点复数矢量对矩阵的每一个3万点矢量做互相关,重复3万次这种互相关。 , C; B1 |5 D+ ]9 T% h! T  ]
    我已经试验成功了 AVX 算浮点内积和 VS 优化, 再加上多核并行,我希望能至少和 octave 打平。但现在手头有其他事,还没有时间改正式代码。
    回复 支持 反对

    使用道具 举报

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

    GMT+8, 2025-7-9 06:13 , Processed in 0.048797 second(s), 22 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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