Upload
otb
View
1.389
Download
3
Embed Size (px)
DESCRIPTION
intel Xeon PhiとOpenACCのプログラミング要領をFDTD法をサンプルにしてまとめてみました.当社はフランスのメニィコア開発支援ベンダーのCAPS社の日本総代理店です. 質問があればご遠慮なくお問合せください.
Citation preview
Xeon Phiを使ったFDTD法の高速化例の紹介- Native, Offload, OpenACC -
2013/07
フランスCAPS社日本総代理店
株式会社JCCギミック
2013/07 2JCC Gimmick Ltd.
はじめに
Intel Xeon Phiを使ったFDTD法による計算の高速化に関して紹介しています.
概要
OpenMPコードをそのままXeon Phi 5110P上で実行した場合、 Xeon CPU E5-2643
(@3.30GHz 4core)と比べて約4~6倍高速になった.
OpenACCコードを使った場合はCPUと比べて約3~4.5倍、OpenACC + HMPPディレ
クティブを加えた場合で約3.9~5.3倍高速になり、OpenACC + OpenCLのXeon Phi上
での実効性を確認することができた.この違いはOpenCL work-groupサイズの設定に
よるものであると思われる.
また、GPUでもOpenACCコードの実行を行って結果を比較し、今回の計算での
OpenACCコードではXeon PhiよりもGPUの方が高速となった.
2013/07 3JCC Gimmick Ltd.
1.Xeon Phiの概要と利用方法
2013/07 4JCC Gimmick Ltd.
Xeon Phi とは?
・インテルMany Integrated Core(MIC)アーキテクチャにもとづくコプロセッサ
・PCI-Express スロットに装着
・x86互換で従来のソースコード、インテルのプログラミングツールなど利用可能
・512bit幅ベクトル命令
Intel Xeon Phi P5110
・60コア/1.053GHz/240スレッドが使用可能
・8GB GDDR5メモリ、ピークメモリバンド幅 320GB/s
2013/07 5JCC Gimmick Ltd.
Intel Xeon Phi の利用方法
Native Mode・OpenMP, pthread, MPIなどで並列化されたコードをXeon Phi向けにコンパイル
・Intel Xeon Phi上でアプリケーション全体を実行
Offload Mode
・OpenMPなどで並列化されたコードにoffload pragmaを挿入
・ソースコードのOffload pragmaの領域をXeon Phiにオフロード
OpenACC + CAPSコンパイラ (OpenCL)
・OpenCLコーディングの必要なくOpenACCディレクティブでOpenCLデバイスとして利用
・Xeon Phi以外にもNVIDIAやAMDのGPUなどでアプリケーションを実行可能
2013/07 6JCC Gimmick Ltd.
Native mode
Intel Xeon Phi上でアプリケーション全体を実行する
特徴
-ソースコード修正の必要なくコンパイルオプションをつけてコンパイル
-全てXeon Phi上で実行するためメモリ使用量は大きくなる
-Many-coreでの並列処理を活かせない部分は現行のXeon CPUよりも遅い
Xeon Phi向けの実行ファイル
Xeon PhiHost機
Dynamic linkLibrary
Xeon Phi向けの実行ファイル
Dynamic linkLibrary
Host上で-mmic オプションをつけてコンパイル Xeon Phi上で実行
scpファイル転送& SSHログイン
2013/07 7JCC Gimmick Ltd.
Offload mode
Offload pragmaを挿入して並列計算部分をXeon Phiにオフロード
計算に必要なデータに関するHostとXeon Phiとの間の転送は自動or手動で管理
特徴
-Offload領域やデータ転送の指示などにはディレクティブの挿入が必要
-ホットスポットとなる並列計算部分だけをIntel Xeon Phi上で実行
-データ転送によるオーバーヘッドが生じる
Intel Xeon PhiHost
init( ) ;
#pragma offload target(mic)#pragma omp parallel forfor ( .... ) {// computation
}
finalize();.....
Offload pragmaで指定した部分が実行
データ転送
ホスト上で実行
2013/07 8JCC Gimmick Ltd.
OpenACC+CAPSコンパイラ(OpenCL)
CAPSコンパイラ + OpenACCによりOpenCLアプリケーション構築
OpenACCはOpenMPライクなディレクティブベースのプログラミングモデル
特徴
-Xeon Phi以外のGPUなどのOpenCL対応デバイスでのアプリケーションの実行が可能
-OpenMP-likeなディレクティブベースなのでOpenCLで記述するより簡単
-Offloadと同様にデータ転送のオーバーヘッドが生じる
C,Fortran code + ディレクティブ
#pragma acc data ...{#pragma acc kernelsfor( i = 0 ; i < N ; i++) {// parallel// computation
}…
}……
OpenACCディレクティブコンパイル
Hybrid Application
CPU GPU, MIC
OpenCLアプリケーション
2013/07 9JCC Gimmick Ltd.
OpenACC+CAPSコンパイラ(OpenCL)での開発のメリット
・OpenCLターゲットのCAPSコンパイラ = XeonPhi以外のデバイスで実行可能
・開発工数の削減 & さまざまな実行環境への迅速な対応
・コードはC/Fortran + ディレクティブなのでメンテナンス・拡張が容易
Executable(mybin.exe)
HWA library(Dyn. library)
CAPSRuntime
C or Fortran code
OpenACC Directive#pragma acc ...
C or Fortran code
OpenHMPP Directive#pragma hmpp ...
CAPS Many-core Compiler$ capsmc --openacc-target opencl gcc sample.c -o mybin.exe
Directive挿入済ソースコード
IntelMIC
NVIDIAGPU
OpenCL kernelcode (.cl)
AMDGPU
1つのコードから各種デバイスで実行可能なOpenCLアプリケーションの開発
OpenCL platform
2013/07 10JCC Gimmick Ltd.
2. 計算対象、使用ハードウェア
(株)OTB製Xeon Phiサーバー
http://www.otb-japan.co.jp
使用ハードウェア
2013/07 11JCC Gimmick Ltd.
FDTD法
電磁波解析において用いられる手法
Maxwell方程式を差分法で離散化して電磁界の解析を行なうものが一般的
電場・磁場の計算では演算よりもメモリアクセスが多く、メモリバンド幅が性能に影響
Yee格子
Ez
Ex Ey
Hz
Hx
Hy
z
y
x
・3次元の直交座標空間
・1次吸収境界条件
・計算格子の中心点のEzをsin関数で変動
・時間進行の反復は1000ステップ
問題設定:
今回はシンプルなケースとして以下のように問題設定を行ない計算を行った.
また、格子点数を200x200x200と300x300x300の2種類とした.
CPUよりメモリバンド幅が大きいXeon Phiで高速化が見込める
2013/07 12JCC Gimmick Ltd.
計算アルゴリズム
時間進行ループ
メモリ確保
配列初期化
電界Ex, Ey, Ezの計算
領域中心点でのEzの計算
境界条件
磁場Hx, Hy, Hzの計算
メモリ破棄
設定された計算回数まで反復計算
2013/07 13JCC Gimmick Ltd.
サンプルソースコード
1. OpenMPとIntel offloadディレクティブ2. OpenACC (+HMPP)
FDTD法による電磁場解析(C言語)
プログラミング方法
テスト環境
(株)OTB製 Xeon Phi 5110P 搭載マシン
OS Linux CentOS 6.3
CPUテスト: Intel Xeon CPU E5-2603 @ 1.80GHz (4 core)実測 : Intel Xeon CPU E5—2643 @3.30GHz (4 core)
メモリ 4GB
コプロセッサ Intel Xeon Phi 5110P
インテルMPSS MPSSバージョン : 2.1.6720-13
OpenCL Intel SDK for OpenCL Application 2013 XE
CPUコンパイラ Intel Composer XE 13.1.0CAPSコンパイラ CAPS Compiler 3.3.4 (OpenCL target)
プログラミング方法とハードウェア
2013/07 14JCC Gimmick Ltd.
3. CPUでの計算
2013/07 15JCC Gimmick Ltd.
Xeon E5-2603 1.80GHz CPUでのホットスポットの特定
CPUでの計算
icc -no-offload -std=c99 -w -O3 -fno-alias -ansi-alias -o fdtd.single ¥fdtd3d.c func.c
コンパイル(1core)
時間進行の反復計算
アプリケーション実行時間の99%以上が時間進行の反復計算(以後、これ以外の部分は省略)
アプリケーション実行時間 : 155.7 sec
2013/07 16JCC Gimmick Ltd.
Intel Xeon CPU E5-2603 @ 1.80GHzで1core vs 4coreの実行時間
CPUでの計算
アプリケーション全体の実行時間
1core 155.7 sec4core 104.0 sec 1.4倍
icc -openmp -no-offload -std=c99 -w -O3 -fno-alias -ansi-alias -o fdtd.host fdtd3d.c func.c
コンパイル(OpenMP)
最適化によって1コアあたりの速度が向上し、スケーリングしなくなっていると思われる※コンパイラ最適化が-O0のときは4コアで3.7倍とマルチコアの効果が現れるため
2013/07 17JCC Gimmick Ltd.
x方向の電場Exの計算
CPUでの計算
#pragma omp parallel shared(Ex, Ey, Ez, Hx, Hy, Hz){#pragma omp for collapse(2)for ( int k = 1 ; k < nz - 1 ; k++)for ( int j = 1 ; j < ny - 1 ; j++)#pragma ivdepfor ( int i = 0 ; i < nx - 1 ; i++) {Ex[IDX(k,j,i)] = ce * Ex[IDX(k,j,i)]+ cexy0 * (Hz[IDX(k,j,i)] - Hz[IDX(k,j-1,i)])- cexz0 * (Hy[IDX(k,j,i)] - Hy[IDX(k-1,j,i)]);
}...
FDTD法の基本的なアルゴリズムを使用しているため、上記のコードに代表される電場Eの各成分と磁場Hの各成分の計算のみに実行時間の大半を費やす.
上記のコードからメモリアクセスの回数に対して演算が少ないため計算密度が低く、
実行速度がメモリ帯域に大きく制限されることが推測される.
※電場E(Ex、Ey、Ez)と磁場H(Hx、Hy、Hz)の計算は変数やアクセスするメモリが違うだけでほぼ同じ構造
2013/07 18JCC Gimmick Ltd.
Xeon Phiとの比較に使用するCPU
CPUでの計算
(1) 最適化オプション-O3時にマルチスレッドによる並列化の効果が低い
(2) メモリバンド幅によって性能が制限されると想定
以上のことから、Xeon Phiとの比較に使用するCPUとしてはコア数の多いCPUではなく、クロック
周波数の高いCPUが望ましいと考え、Intel Xeon CPU E5-2643 @3.30GHz (4 core)を選定
2013/07 19JCC Gimmick Ltd.
4. Xeon Phiでの計算方法について
2013/07 20JCC Gimmick Ltd.
Xeon PhiのNativeモードによる計算
icc -mmic -no-offload -openmp -vec-report -openmp-report -std=c99 -w -O3 -fno-alias ¥-ansi-alias -o fdtd.mic fdtd3d.c func.c
scp ./fdtd.mic /usr/local/intel/composer_xe_2013.2.146/compiler/lib/mic/libiomp5.so ¥mic0:/tmp
コンパイル後、必要なファイルをscpによってXeon Phi (ホスト名mic0)に転送
1.作成したMIC向けのバイナリ fdtd.mic
2. intelのOpenMPライブラリ libiomp5.so
sshでXeon Phiにアクセスしてアプリケーションを実行
OpenMPコードをそのままXeon Phi向けにコンパイルして使用した
※ただしメモリの動的確保時に_mm_mallocで64バイト境界を指定しており、これ以降のPhiでの計算においては全てそのようにしている
2013/07 21JCC Gimmick Ltd.
Xeon PhiのOffloadモードによる計算
メモリ確保
配列初期化
電界Ex, Ey, Ezの計算
中心点のEzソースの計算
境界条件
磁場Hx, Hy, Hzの計算
メモリ破棄
データ転送 Host => Device
データ転送 Device => Host
offloadディレクティブによりデータ転送を追加
各関数にoffloadを行なうためのディレクティブを追加
Offloadモードではデータ転送などを明示的に行なっている
2013/07 22JCC Gimmick Ltd.
1.offloadする関数を指定
Xeon PhiのOffloadモードによる計算
関数の定義
__attribute__((target(mic:0))) void updateE (int nx, int ny, ...){...
}
関数呼び出し
#pragma offload target(mic:0) nocopy(Ex) nocopy(Ey) nocopy(Ez)nocopy(Hx) nocopy(Hy) nocopy(Hz)
updateE(nx, ny, nz, ...);...
#pragma offload target(mic:0) nocopy(Ex) nocopy(Ey) nocopy(Ez)nocopy(Hx) nocopy(Hy) nocopy(Hz)
updateH(nx, ny, nz, ...);
Xeon Phi (mic0)に対してオフロードするために記述
オフロードするターゲットとオフロード時のデータ転送の設定(nocopy = データ転送なし)
2013/07 23JCC Gimmick Ltd.
Xeon PhiのOffloadモードによる計算
2. データ転送を行なうためのディレクティブを追加
#pragma offload_transfer target(mic:0) in(Ex[0:nx*ny*nz] : alloc_if(1) free_if(0))in(Ey[0:nx*ny*nz] : alloc_if(1) free_if(0)) ...{}
for ( nstep = 1 ; nstep <= maxiter ; nstep++){
#pragma offload target(mic:0) nocopy(Ex) nocopy(Ey) nocopy(Ez) nocopy(Hx) nocopy(Hy) nocopy(Hz)updateE(nx, ny, nz, ...);……
}
#pragma offload_transfer target(mic:0) out(Ex[0:nx*ny*nz]: alloc_if(0) free_if(1))out(Ey[0:nx*ny*nz]: alloc_if(0) free_if(1)) ...{}
ホストからデバイスへのデータ転送境界条件用の配列など含めて全ての転送
ループの外で全てデータ転送を実行ループ内ではホスト上でのデータ更新は不要
デバイスからホストへのデータ転送必要な結果Ex, Ey, Ez, Hx, Hy, Hzのみ指定
2013/07 24JCC Gimmick Ltd.
Xeon PhiのOffloadモードによる計算
コンパイル時には特別なオプションは不要
icc -openmp -std=c99 -w -O3 -fno-alias -ansi-alias -o fdtd.offload fdtd3d.c func.c
実行時に環境変数OFFLOAD_REPORT= n (nは1~3)を指定することで、データ転送量や経過時間が表示される
[Offload] [MIC 0] [File] fdtd3d.c[Offload] [MIC 0] [Line] 660[Offload] [MIC 0] [Tag] Tag0[Offload] [MIC 0] [CPU Time] 0.000000 (seconds)[Offload] [MIC 0] [CPU->MIC Data] 391680000 (bytes)[Offload] [MIC 0] [MIC Time] 0.000263 (seconds)[Offload] [MIC 0] [MIC->CPU Data] 144 (bytes)
[Offload] [MIC 0] [File] fdtd3d.c[Offload] [MIC 0] [Line] 713[Offload] [MIC 0] [Tag] Tag1[Offload] [MIC 0] [CPU Time] 0.000000 (seconds)[Offload] [MIC 0] [CPU->MIC Data] 116 (bytes)[Offload] [MIC 0] [MIC Time] 0.344718 (seconds)[Offload] [MIC 0] [MIC->CPU Data] 48 (bytes)
2013/07 25JCC Gimmick Ltd.
OpenACC+CAPSコンパイラによる計算
メモリ確保
配列初期化
電界Ex, Ey, Ezの計算
中心点のEzソースの計算
境界条件
磁場Hx, Hy, Hzの計算
メモリ破棄
データ転送 Host => Device
データ転送 Device => Host
変更点1.kernelsディレクティブ2.HMPPディレクティブによるwork-sizeの変更
3.dataディレクティブ
CPUコードに対してOpenACCディレクティブを追加した
2013/07 26JCC Gimmick Ltd.
1. OpenACCディレクティブによるカーネルの指定
OpenACC+CAPSコンパイラによる計算
void updateE(int nx, int ny, int nz, double* restrict Ex, double* restrict Ey, ...){
#pragma acc kernels present(Ex[:nx*ny*nz], Ey[:nx*ny*nz], Ez[:nx*ny*nz], ¥Hx[:nx*ny*nz], Hy[:nx*ny*nz], Hz[:nx*ny*nz])
{#pragma acc loop independent collapse(2)for ( int k = 1 ; k < nz - 1 ; k++)for ( int j = 1 ; j < ny - 1 ; j++)#pragma acc loop independentfor ( int i = 0 ; i < nx - 1 ; i++) {Ex[IDX(k,j,i)] = ce * Ex[IDX(k,j,i)]+ cexy0 * (Hz[IDX(k,j,i)] - Hz[IDX(k,j-1,i)])- cexz0 * (Hy[IDX(k,j,i)] - Hy[IDX(k-1,j,i)]);
}
…… 以下、EyとEzの計算}
}
1つのkernels領域でEx, Ey, Ezの3つのループネストを囲む
各反復においてデータ依存性はないのでIndependentclauseを指定できる.また、最外側でcollapse(2)を指定して、外側の2つのループを一つにまとめている.
OpenMPのparallel forがOpenACCのkernelsとloopディレクティブに相当すると考えればよい
2013/07 27JCC Gimmick Ltd.
OpenACC+CAPSコンパイラによる計算
2. OpenCLカーネルのwork-groupサイズ最適化
void updateE(int nx, int ny, int nz, double* restrict Ex, double* restrict Ey, ...){
#pragma acc kernels present(Ex[:nx*ny*nz], Ey[:nx*ny*nz], Ez[:nx*ny*nz], ¥Hx[:nx*ny*nz], Hy[:nx*ny*nz], Hz[:nx*ny*nz])
{#pragma hmppcg gridify(k*j,i) blocksize "256x4"for ( int k = 1 ; k < nz - 1 ; k++)for ( int j = 1 ; j < ny - 1 ; j++)for ( int i = 0 ; i < nx - 1 ; i++) {Ex[IDX(k,j,i)] = ce * Ex[IDX(k,j,i)]+ cexy0 * (Hz[IDX(k,j,i)] - Hz[IDX(k,j-1,i)])- cexz0 * (Hy[IDX(k,j,i)] - Hy[IDX(k-1,j,i)]);
}
…… 以下、EyとEzの計算}
}
CAPSのHMPPディレクティブを使用してwork-groupのサイズ設定を行なっている.これは、Independent clauseあるいはgang, worker, vectorの数を指定した場合の結果があまり良くなかったためにとった方法である.
以後、結果の凡例でのOpenACCという項目名はindependentclause を設定した結果を、OpenACC+HMPPという項目名はこのwork-groupサイズの最適化を行なった結果を示す.
2013/07 28JCC Gimmick Ltd.
3. OpenACCディレクティブによるデータ転送の指定
OpenACC+CAPSコンパイラによる計算
#pragma acc data copy(Ex[0:nx*ny*nz], Ey[0:nx*ny*nz], Ez[0:nx*ny*nz], ¥Hx[0:nx*ny*nz], Hy[0:nx*ny*nz], Hz[0:nx*ny*nz]), ¥
copyin(eyx0[0:2*ny*nz], eyx1[0:2*ny*nz], ezx0[0:2*ny*nz], ¥ezx1[0:2*ny*nz], exy0[0:2*nx*nz], exy1[0:2*nx*nz], ¥ezy0[0:2*nx*nz], ezy1[0:2*nx*nz], eyz0[0:2*nx*ny], ¥eyz1[0:2*nx*ny], exz0[0:2*nx*ny], exz1[0:2*nx*ny] )
for ( nstep = 1 ; nstep <= maxiter ; nstep++) {……updateE(nx, ny, nz, ...);……updateH(nx, ny, nz, ...);……
} ループに入る前に全てのデータをHost => Deviceに転送
ループから抜けたときにE, Hに関するデータをDevice => Hostに転送
2013/07 29JCC Gimmick Ltd.
コンパイル
OpenACC+CAPSコンパイラによる計算
capsmc --codelet-required -f --openacc-target opencl icc -no-offload -std=c99 -w -O3-fno-alias -ansi-alias -o fdtd.acc fdtd3d.c func.c
CAPSコンパイラによるコンパイルでは、CPUでのコンパイルコマンドの前にCAPSコンパイラのコマンドとオプションをつけるだけで使用可能
hmppcg: [Message DPL3001] fdtd3d.c:375: Loops 'i' and 'k*j' were gridified (2D)hmppcg: [Message DPL3001] fdtd3d.c:392: Loops 'i' and 'k*j' were gridified (2D)hmppcg: [Message DPL3001] fdtd3d.c:410: Loops 'i' and 'k*j' were gridified (2D)capsmc: [Info] Generated codelet filename is"__hmpp_acc_region__updateH_361__ir7tu1gq_opencl.hmf.cl".hmppcg: [Message DPL3001] fdtd3d.c:459: Loops 'i' and 'k*j' were gridified (2D)hmppcg: [Message DPL3001] fdtd3d.c:476: Loops 'i' and 'k*j' were gridified (2D)hmppcg: [Message DPL3001] fdtd3d.c:493: Loops 'i' and 'k*j' were gridified (2D)capsmc: [Info] Generated codelet filename is"__hmpp_acc_region__updateE_448__o4exe9ex_opencl.hmf.cl".
OpenACC+CAPSコンパイラではOpenCLデバイスとして各種デバイスを利用できるため、今回は一つのコードを使用してXeon Phiの他にGPU (NVIDIA Geforce GTX480) でのアプリケーション実行も行った
2013/07 30JCC Gimmick Ltd.
5. 計算結果
2013/07 31JCC Gimmick Ltd.
アプリケーションの実行時間
格子点数200x200x200
・Xeon E2643 4コアと比較すると、Native, Offload, OpenACC+HMPPでは3.8~4倍程度高速化された
・OpenACCのみの場合は3倍程度高速にはなったが、他のケースに比べてやや遅い.これは前述のようにwork-groupサイズが適切でないためと思われる
2013/07 32JCC Gimmick Ltd.
アプリケーションの実行時間
格子点数300x300x300
・Xeon E2643 4コアと比較するとXeon Phiでは5.3~6倍程度高速化されている
・NativeがCPUより6倍程度と最も速く、OffloadはNativeと数%の違いしかない
・OpenACC+HMPPではCPUより5.3倍程度高速で、Offloadとの違いは10%程度である
・OpenACCのみではCPUより4.5倍程度高速である
2013/07 33JCC Gimmick Ltd.
アプリケーションの実行時間
各計算部分での実行時間とデータ転送時間
2013/07 34JCC Gimmick Ltd.
OpenACCコードのXeon PhiとGPUでの実行時間の比較
格子点数200x200x200GPU : NVIDIA Geforce GTX 480
・OpenACCコーディングでの性能としては、Fermi世代のNVIDIA Geforce GTX 480の方が5110Pより高速であり、最新のTesla K20であればさらに高速になることが推測できる
・CPUコードレベルでの最適化も含め、Xeon Phi、GPUともにチューニングで性能が向上する余地はあると思われる
2013/07 35JCC Gimmick Ltd.
6. まとめ
2013/07 36JCC Gimmick Ltd.
Xeon Phiで基本的なFDTD法の計算を実行し、以下のような結果が得られた.
(1) 特別な最適化をほどこしていないOpenMPコードをそのまま利用したXeon PhiのNativeモードでは約4~6倍高速化できた.今回の問題に対してCPUにXeon E2643を2個使用したとし
ても、2~3倍程度の高速化は期待できると思われる.
(2) Xeon PhiのOffloadモードでは、主要な計算部分が全てXeon Phi上で並列計算可能であ
りデータ転送回数が少ないため、Nativeモードと同程度の性能となった.
(3) OpenACCのみではwork-groupサイズの最適化がうまくいかず、3~4.5倍程度の性能向
上にとどまった.一方、OpenACCコード内にHMPPディレクティブを使ってwork-groupのサイ
ズを変更した場合、3.9~5.3倍と性能向上が確認された.今回のようなアプリケーションでは
OpenCLのwork-groupの設定が性能に影響を及ぼすと思われる.
(4) OpenACC+HMPPコードをXeon PhiとGPUの両方で実行させた結果、一世代前のGPUの方がXeon Phiよりも高速であり、最新のGPUを使用することによりさらに高速化できると思
われる.
(5) 今回取り上げた計算においては、work-groupのサイズを設定したOpenACCアプリケーシ
ョンのXeon Phi上での性能はOffloadと比較して10%程度の差であった.そのため、Xeon PhiにおいてもOpenACC(OpenCL)アプリケーションが十分利用可能であると思われる.
2013/07 37JCC Gimmick Ltd.
当社ではCAPSコンパイラやメニコアプログラミングに関するトレーニング、ポー
ティング、コンサルティングなどサービスのご相談をお受けしています
また、当社パートナーであるLinux並列計算機に実績をもつ(株)OTBでは
Xeon PhiやGPU搭載のハードウェアから計算環境の構築まで対応いたします.
ハードウェアに関するご相談は当社もしくは(株)OTBにお問い合わせ下さい
トレーニング、コンサルティング、ポーティングなど各種サービス
ハードウェア+計算機環境の構築
http://www.otb-japan.co.jp
http://www.jcc-gimmick.com
ハードウェアからソフトまでトータルに対応!