近年のCPUのほとんどはマルチコアであり、それらの性能を引き出すためには並列プログラミングが必須となっている。そこで当研究室では Cerium Library の開発を行い、提供することによって並列プログラミングを容易にしている。
先行研究では Task の並列化によって、プログラム全体の処理速度は向上しているが、ファイル読み込み等の I/O に対して並列に Task が動作するようにはされていない。
本研究では I/O と Task の並列化の設計、実装によってプログラム全体の処理速度、処理効率を上げていく。
|
CpuThreads、Schedulerに対応させる形でGpuThreadsとGpuSchedulerを作成した
__kernel void // kernel.cl(kernel file) twice(__global int *input_data,__global int *output_data) { long count = (long)data_count[0]; for (int i = 0; i< count; i++) { output_data[i] = input_data[i] * 2;; } }
void task_init(void) { // task_init.cc GpuSchedRegister(Twice, "./twice.cl", "twice"); }
第1引数 Twice |
Taskのid。enumで定義されている TaskManagerはこの値でTaskを識別する |
第2引数 "./twice.cl" |
OpenCLが処理するkernelが記述されているファイルのパス |
第3引数 "twice" |
関数の指定。kernel file内にある、実行する関数名を指定 Taskにあたる部分 |
// main.cc HTaskPtr twice = manager->create_task(Twice); twice->set_inData(0, indata, sizeof (int)*length); // twice->set_inData(1, indata2, sizeof (int)*length); twice->set_outData(0, outdata, sizeof (int)*length); twice->set_cpu(GPU); twice->spawn();
|
10万入力によるBitonic Sort実験環境 OS : MacOS 10.8.2CPU : 2*2.66GHz 6-CoreIntel Xeon Memory : 16GB Compiler : Apple clang version 4.1 (based on LLVM 3.1svn) GPU : AMD ATI Radeon HD 5870 1024MB 結果1coreのCPUよりも10倍遅い |
充分な性能が出なかったため、一度に送信する data のサイズを増やす改善を行ったところ、 約60倍程実行速度が向上した
性能向上は見られたが、CPUと比べると未だ差が開いている GPU向けに適切なチューニングが今後の課題となる
データを2、3次元に分割し、分割した部分に対して並列処理する並列化手法。
OpenCL ではin/outするデータ郡をWork Itemと呼ぶ。
各Work Item のサイズを指定するとOpenCLがデータ並列で実行する。 |
GpuSchedulerはCommand Queueの内部でパイプライン的に実行を行っている。 パイプラインを構成するには処理にwaitをかける必要がある。現在はclWaitForEvent APIを使用
API | 機能 |
clFlush() | Command Queueに投入したTask全てをDeviceで実行する |
clWaitForEvent() | 特定の処理の終了を待つ |
clFlushは実行は保証するが、終了は保証しない仕様になっている
FrameWork | Dependency |
Cerium | Task Dependency |
OpenCL | Data Dependency |
Task Dependency:Schedulerで依存関係が決定
Data Dependency:GPUに読み込まれた時に決定
GPGPUはなるべくGPU内部で処理を行う方が高速なため、性能向上が見込める
|
word count10MBのテキストファイルを分割 スペースと改行区切りでword countしていく 結果CPUの方が150倍早い |