2023-07-22
#js #C 
曲を周波数解析DFTするととんでもない時間がかかることがわかったので、工夫しがいがありそうです。JavaScriptからC言語に書き直し、GPU活用を前に、ひとまずCPUのマルチコアに対応させてみたところ、15倍速にまでなりました。


pthreadを使って、M1 Macbook Pro、パフォーマンスコア6つがフル稼働するマルチスレッド対応のDFT!(src on GitHub)
Deno JavaScriptで44100サンプルのDFT(離散フーリエ変換)にかかった時間は、33.18秒。C言語化で11.78秒と3倍速。マルチコア活用で2.25秒と更に5倍速になりました。


使用するスレッド数を増やしながら実時間とCPU時間を計測してグラフ化したものです。M1 Macbook Proの実コア数6コに対応する6スレッドまで順調に時間は短縮され、以後、CPU時間が若干上昇しますがそのままだいたい安定するようです。コア数が多いCPU、Intel Core i9-13900KS(24コア32スレッド)や、AMD Ryzen Threadripper PRO 5995WX(64コア128スレッド)などでの挙動が気になります。

C言語でのデータの読み書き用にシンプルな単一型の配列バイナリデータ(i32.bin/f32.bin)を採用しました。シングルコアで動作するDFT in C言語はこのように書けます。 #include <stdio.h> #include "readFloatFromInt16.h" #include "dft.h" #include "writeFloat.h" #include "performanceNow.h" int main() { const char* fn = "sekaideichiban.wav-r.i16.bin"; const char* fnre = "sekaideichiban.wav-re.f32.bin"; const char* fnim = "sekaideichiban.wav-im.f32.bin"; size_t len = 0; float* src = readFloatFromInt16(fn, &len); if (!src) { return 1; } // DFT double now = performanceNow(); float* re = (float*)malloc(len * sizeof(float)); float* im = (float*)malloc(len * sizeof(float)); dft(src, len, re, im); double dt = performanceNow() - now; printf("time: %f\n", dt); // 44100samples, time: 14.769461 writeFloat(fnre, re, len); writeFloat(fnim, im, len); free(re); free(im); free(src); return 0; } 次は、いよいよCUDA C。GPU活用でどのくらい高速化するでしょう!?

links
- あえて低速、離散フーリエ変換 DFT in Pure JavaScript
- コンピューターをフル活用しよう! 高専DCONテレビ放映とCUDAでライフゲーム
- ブラウザ上でデータを見える化、DataViewer extends HTMLElement

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS