OpenCLでCPU/GPUを使い分ける?
最近、PG-Stromに興味があるという方からちょくちょく、個別に質問メールを頂く事がある。
その中で頂いたコメントに興味深い洞察が。
GPUによるアクセラレーションは確かに興味深い機能だけれども、PG-Stromの本質は突き詰めていえばパイプライン処理のお化けだよね?だから、計算処理をCPUでやるようにしても良いんじゃない?
確かに。GPUによる並列処理はハマると物凄い費用対効果をもらたすけれども、例えば正規表現マッチみたく、GPU向きじゃない処理もある。
PG-Stromの場合、SQLのWHERE句に与えられた条件から行を評価する関数を自動的に生成、それをJITコンパイルして実行する。たぶん、プランナの時点でCPU実行用、GPU実行用の2種類の関数を自動的に生成して、計算サーバに渡すという処理は実現可能だろう。
NVidiaのGPUを前提とするCUDAと異なり、OpenCLはAMDのGPUやIntelのXeon Phiもサポートする。それどころか、OpenCL Cで書かれたコードをCPU用にコンパイルする事も可能。
その辺の事情もあり、今、PG-StromをOpenCLで再実装し直している。(works in progress)
だが、CPUとGPU用にそれぞれ計算サーバ書くのか、実装が複雑になってやだなぁ~と思っていたところ、実は勘違いである事が判明。
以下のgpuinfoコマンドの出力は、NVidiaのCUDA 4.2と、IntelのOpenCL SDKをインストールした環境でのもの。
なんと、Platform-1でGPUが、Platform-2でCPUが認識されている。
NVidiaのOpenCLライブラリでも、IntelのOpenCLライブラリでも同様。
という事はですよ、要求された計算の特性に応じて、1個の計算サーバでCPU/GPUを使い分けるという芸当もできるという事になるじゃありませんか。
いやー、面白い。実装意欲を掻き立てられる。
なお、以下のコマンド gpuinfo のURLは↓です。
https://github.com/kaigai/gpuinfo
[kaigai@iwashi gpuinfo]$ ./gpuinfo platform-index: 1 platform-vendor: NVIDIA Corporation platform-name: NVIDIA CUDA platform-version: OpenCL 1.1 CUDA 4.2.1 platform-profile: FULL_PROFILE platform-extensions: cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll Device-01 Device type: GPU Vendor: NVIDIA Corporation (id: 000010de) Name: GeForce GT 640 Version: OpenCL 1.1 CUDA Driver version: 310.32 OpenCL C version: OpenCL C 1.1 Profile: FULL_PROFILE Device available: yes Address bits: 32 Compiler available: yes Double FP config: Denorm, INF/NaN, R/nearest, R/zero, R/INF, FMA Endian: little Error correction support: no Execution capability: kernel, native kernel Extensions: cl_khr_byte_addressable_store cl_khr_icd \ cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query \ cl_nv_pragma_unroll cl_khr_global_int32_base_atomics \ cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics \ cl_khr_local_int32_extended_atomics cl_khr_fp64 Global memory cache size: 32 KB Global memory cache type: read-write Global memory cacheline size: 128 Global memory size: 2047 MB Host unified memory: no Image support: yes Image 2D max size: 32768 x 32768 Image 3D max size: 4096 x 4096 x 4096 Local memory size: 49152 Local memory type: SRAM Max clock frequency: 901 Max compute units: 2 Max constant args: 9 Max constant buffer size: 65536 Max memory allocation size: 511 MB Max parameter size: 4352 Max read image args: 256 Max samplers: 32 Max work-group size: 1024 Max work-item sizes: {1024,1024,64} Max write image args: 16 Memory base address align: 4096 Min data type align size: 128 Native vector width - char: 1 Native vector width - short: 1 Native vector width - int: 1 Native vector width - long: 1 Native vector width - float: 1 Native vector width - double: 1 Preferred vector width - char: 1 Preferred vector width - short: 1 Preferred vector width - int: 1 Preferred vector width - long: 1 Preferred vector width - float: 1 Preferred vector width - double: 1 Profiling timer resolution: 1000 Queue properties: out-of-order execution, profiling Sindle FP config: Denorm, INF/NaN, R/nearest, R/zero, R/INF, FMA platform-index: 2 platform-vendor: Intel(R) Corporation platform-name: Intel(R) OpenCL platform-version: OpenCL 1.2 LINUX platform-profile: FULL_PROFILE platform-extensions: cl_khr_fp64 cl_khr_icd cl_khr_global_int32_base_atomics \ cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics \ cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store \ cl_intel_printf cl_ext_device_fission cl_intel_exec_by_local_thread Device-01 Device type: CPU Vendor: Intel(R) Corporation (id: 00008086) Name: Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz Version: OpenCL 1.2 (Build 56860) Driver version: 1.2 OpenCL C version: OpenCL C 1.2 Profile: FULL_PROFILE Device available: yes Address bits: 64 Compiler available: yes Double FP config: Denorm, INF/NaN, R/nearest, R/zero, R/INF, FMA Endian: little Error correction support: no Execution capability: kernel, native kernel Extensions: cl_khr_fp64 cl_khr_icd \ cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics \ cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics \ cl_khr_byte_addressable_store cl_intel_printf cl_ext_device_fission \ cl_intel_exec_by_local_thread Global memory cache size: 256 KB Global memory cache type: read-write Global memory cacheline size: 64 Global memory size: 386942 MB Host unified memory: yes Image support: yes Image 2D max size: 16384 x 16384 Image 3D max size: 2048 x 2048 x 2048 Local memory size: 32768 Local memory type: DRAM Max clock frequency: 2600 Max compute units: 32 Max constant args: 480 Max constant buffer size: 131072 Max memory allocation size: 96735 MB Max parameter size: 3840 Max read image args: 480 Max samplers: 480 Max work-group size: 1024 Max work-item sizes: {1024,1024,1024} Max write image args: 480 Memory base address align: 1024 Min data type align size: 128 Native vector width - char: 16 Native vector width - short: 8 Native vector width - int: 4 Native vector width - long: 2 Native vector width - float: 4 Native vector width - double: 2 Preferred vector width - char: 16 Preferred vector width - short: 8 Preferred vector width - int: 4 Preferred vector width - long: 2 Preferred vector width - float: 4 Preferred vector width - double: 2 Profiling timer resolution: 1 Queue properties: out-of-order execution, profiling Sindle FP config: Denorm, INF/NaN, R/nearest