Show page source of Parallel_Studioを活用したソフトウェアの並列化:AACエンコーダを高速化する_p4 #49793

[[PageNavi(NavigationList)]]



==== OpenMPによる並列処理の実装 ====


 Parallel Amplifierの実行結果より、wav_read_float32()関数やrfft()関数、!FixNoise()関数、AACQuantize()関数などについて何らかの並列化を行えばよい、という指針が得られた。そこで、これらの関数を呼び出している関数に対して、並列化できる個所がないかを探して行くこととなる。


 ここでソースコードを分析してみると、fft_proc()関数は「!PsyBufferUpdate()」関数から呼ばれており、!FixNoise()関数は「AACQuantize()」関数、!QuantizeBand()は!FixNosie()関数内で呼び出されていることが分かった。さらに、!PsyBufferUpdate()およびAACQuantize()関数はfaac!EncEncode()関数内で呼び出されている('''図8''')。つまり、faac内では多数のループが呼びされているのだが、faac!EncEncode()関数はこれらのループのうちもっとも外側で呼びだされているのである。
[[Thumb(275ae6b8295dd9112bbd3e24bec518f5.png, caption=図8 faacによるエンコード処理の流れ)]]



 そこで、まずはaac!EncEncode()の実行を並列化し、複数のスレッドで同時実行する方針で実装を行うことにする。faacのエンコーダ部はスレッドセーフな実装になっているので、複数のエンコーダを用意し、読み込んだデータを並列にエンコードして読み込んだ順に出力する、という流れである。


 詳細については記事末のソースコードを参照してほしいが、変更を加えた点を簡単にまとめると下記のようになる。
 * エンコーダのインスタンスを複数用意
 * 処理のメインループを複数のスレッドで同時処理
 * 入力データは読み出した順にシーケンスIDを付け、エンコード後はシーケンスIDの順番にデータを出力



 このような並列化を行ったところ、先ほどと同じテスト環境('''表2''')では実行時間が約50%削減できることが確認できた('''表3''')。
{{{ html
<h6>表3 並列化による高速化結果</h6>
<table class="wikitable" border="1">

<tr><th>ソースコード</th><th>コンパイラ</th><th>実行時間</th></tr>
<tr><td rowspan="2">オリジナルfaac</td><td>Visual C++</td><td>10.7秒</td></tr>
<tr><td>インテル コンパイラー</td><td>8.8秒</td></tr>
<tr><td rowspan="2">並列化版faac</td><td>Visual C++</td><td>5.3秒</td></tr>
<tr><td>インテル コンパイラー</td><td>4.6秒</td></tr>

</table>
}}}


[[PageNavi(NavigationList)]]