読者です 読者をやめる 読者になる 読者になる

Pebble's Diary

プログラマーの作業メモ

iOS/MacOSXのvDSP関数、多すぎてなかなか見つけられないのをなんとかする(基礎編)

iOS/MacOSXのvDSP関数というのは、サンプル数が多くなるほど、for文をまわすより確実に処理速度があがります。
驚くことにSIMD組み込み関数を使うよりも速く、アセンブラ命令によってかなりの最適化が入っているようです。
俺のアプリは信号処理なんてやってないよという人も、例えば、256個の変数の合計値を計算するときや、256個の変数を全て0でクリアする時などにも実は使えるのです。

ただvDSP関数は数が多すぎて、どれが目的にあっているのか探すのがかなり面倒です。
そこで、ここにメモしておくことにします。

Appleの資料

vDSPを使うことによるパフォーマンスアップが重要な場合のみ使うのが適した使い方になるでしょう。

iOSの場合はMacOSXよりも使えるAPIの種類が限られています。
ここではiOSで使えるもののみをリストアップしています。

Appleのドキュメントでは、機能毎にグループ化されてリストアップされています。
関数の名前は全てvDSP_で始まります。
ほとんどの関数は、float値のベクターを引数に持ちます。
つまり、
float buf[256];
のようなバッファを使います。

関数の末尾にDがついているものはfloat値ではなく、double値のベクターを引数に使うだけで
機能は同じなのでここでのリストからは省きます。

関数の末尾に15とか24とかついているものは、固定少数点値のベクターを引数に
使うので、これもリストからは省きます。

関数の先頭がzのものは複素数を引数に使うものです。これもリストから省きます。
フーリエ変換、ウィンドウ、フィルター関連もリストから省きます。
割と使うものには★をつけておきます。

基本演算

1) 単一ベクター絶対値

vDSP_vabs
vDSP_vabsi
vDSP_vnabs

2) 単一ベクターマイナス値

vDSP_vneg
vDSP_zvneg

3) 単一ベクター値埋めもしくはクリア

vDSP_vfill
vDSP_vfilli
vDSP_vclr ★  要素を全て0.0で埋める

4) 単一ベクター生成

vDSP_vramp    C n = a + n*b     n = {0, N-1} 先頭の要素の値がa、傾きがbの線形の坂を生成
vDSP_vrampmul  ★ ベクターに坂状の係数を掛ける     
vDSP_vrampmul2    上記のステレオバージョン
vDSP_vrampmuladd    ベクターに坂状の係数を掛けて追加する
vDSP_vrampmuladd2    上記のステレオバージョン
vDSP_vgen    C n = A + n*(B-A)/(N-1)      n = {0,N-1} 先頭の要素の値がA,終端の要素の値がBとなる線形の坂を生成
vDSP_vgenp    少ない点数のデータの中間値を補完して、間延びしたデータを生成する
vDSP_vtabi    ルックアップ波形で変換したデータを生成する

5) 単一ベクター2乗

vDSP_vsq
vDSP_vssq

6) 単一ベクター極座標変換

vDSP_polar
vDSP_rect

7) 単一ベクターデジベル変換 

vDSP_vdbcon

8) 単一ベクター少数部取り出し

vDSP_vfrac

9) 単一ベクタークリップ、リミット、スレッショルド

vDSP_vclip         下限値a,上限値bを与えクリップする
vDSP_vclipc
vDSP_viclip
vDSP_vlim
vDSP_vthr         最小値スカラーBを与え、その値以下の場合、Bを設定する
vDSP_vthres     最小値スカラーBを与え、その値以下の場合、0を設定する
vDSP_vthrsc

10) 単一ベクター圧縮

vDSP_vcmprs

11) 単一ベクター収集

vDSP_vgathr
vDSP_vgathra
vDSP_vindex

12) 単一ベクターリバース

vDSP_vrvrs

13) 単一ベクターゼロクロスサーチ 

vDSP_nzcros

14) 単一ベクター線形平均

vDSP_vavlin

15) 単一ベクター線形内挿

vDSP_vlint

16) 単一ベクター積分

vDSP_vrsum
vDSP_vsimps
vDSP_vtrapz

17) 単一ベクターソート

vDSP_vsort
vDSP_vsorti

18) 単一ベクタースライドウィンドウ足し上げ

vDSP_vswsum

19) 単一ベクター精度変換

vDSP_vdpsp
vDSP_vspdp

20) 単一ベクター浮動小数点から整数への変換

vDSP_vfix8
vDSP_vfix16
vDSP_vfix32
vDSP_vfixr8
vDSP_vfixr16
vDSP_vfixr32
vDSP_vfixu8
vDSP_vfixu16
vDSP_vfixu32
vDSP_vfixru8
vDSP_vfixru16
vDSP_vfixru32

21) 単一ベクター整数から浮動小数点への変換

vDSP_vflt8
vDSP_vflt16
vDSP_vflt32
vDSP_vfltu8
vDSP_vfltu16
vDSP_vfltu32

22) ベクター-スカラー加算

vDSP_vsadd ★        Cn = An + B
vDSP_vsaddi

23) ベクター-スカラー除算

vDSP_vsdiv ★ Cn = An / B
vDSP_vsdivi
vDSP_svdiv
vDSP_svdivD

24) ベクター-スカラー積算

vDSP_vsma     Dn = An * B + Cn
vDSP_vsmul    Cn = An * B

25) ベクター-スカラー積算、加算

vDSP_vsmsa
vDSP_vsmsb

26) ベクターからベクターベクター基本演算

vDSP_vadd ★  Cn = An + Bn
vDSP_vsub Cn = An - Bn
vDSP_vam Dn = (An + Bn) * Cn
vDSP_vsbm Dn = (An - Bn) * Cn
vDSP_vaam  En = (An + Bn) * (Cn + Dn)
vDSP_vsbsbm  En = (An - Bn) * (Cn - Dn)
vDSP_vasbm En = (An + Bn) * (Cn - Dn)
vDSP_vasm Dn = (An + Bn) * C
vDSP_vsbsm Dn = (An - Bn) * C
vDSP_vmsa Dn = An * Bn + C
vDSP_vdiv ★  Cn = Bn / An
vDSP_vmul ★  Cn = An * Bn
vDSP_vma Dn = An * Bn + Cn
vDSP_vmsb Dn = An * Bn - Cn
vDSP_vmma En = An * Bn + Cn * Dn
vDSP_vmmsb En = An * Bn - Cn * Dn
vDSP_vaddsub

27) ベクターからベクター、整数演算
vDSP_veqvi
vDSP_vdivi

28) ベクターからベクター、最大値、最小値

vDSP_vmax ★  
vDSP_vmaxmg
vDSP_vmin
vDSP_vminmg

29) ベクターからベクター、距離計算

vDSP_vdist
vDSP_vdistD
vDSP_distancesq

30) ベクターからベクター、内挿

vDSP_vintb
vDSP_vqint

31) ベクターからベクター多項式評価

vDSP_vpoly

32) ベクターからベクターピタゴラス計算

vDSP_vpythg

33) ベクターからベクター極値検出

vDSP_venvlp

34) ベクターからベクター、要素スワップ
vDSP_vswap

35) ベクターからベクター、マージ
vDSP_vtmerg

36) ベクターからベクター、実ベクタ、再帰的フィルタ

vDSP_deq22

37) 2つのベクタの内積
vDSP_dotpr
vDSP_dotpr2

38) 最大値検出

vDSP_maxv       最大値 
vDSP_maxvi
vDSP_maxmgv  絶対値の最大値
vDSP_maxmgvi

39) 最小値検出
vDSP_minv
vDSP_minvi
vDSP_minmgv
vDSP_minmgvi

40) 平均値
vDSP_meanv ★  要素の合計をNで割る
vDSP_meamgv    要素の絶対値の合計をNで割る
vDSP_measqv     要素の2乗の合計をNで割る
vDSP_mvessq   要素と要素の絶対値の積の合計をNで割る
vDSP_rmsqv  要素の2乗の合計をNで割り平方根を取る

41) 合計値

vDSP_sve ★  要素の合計
vDSP_svemg 要素の絶対値の合計
vDSP_svesq  要素の2乗の合計
vDSP_svs 要素と要素の絶対値の積の合計
vDSP_sve_svesq 要素の合計と要素の2乗の合計を同時に計算する

42) 行列計算

vDSP_mmul

43) 行列変換
vDSP_mtrans

44) 行列、部分行列コピー
vDSP_mmov

45) ベクターからベクター整数演算(int)
vDSP_vaddi   Cn = An + Bn (iOS7以上,OSX?)
vDSP_veqvi   Cn = An XNOR Bn
vDSP_vdivi   Cn = An / Bn