Archive

Archive for the ‘GPU・GPGPU関連’ Category

LinuxでCUDAのプロファイラを使う方法のメモ

1月 23rd, 2010

後輩某氏に聞かれたので、せっかくだからまとめておく。

WindowsならVisualProfilerで簡単なんだけどね。

環境はCUDA_2.3。/usr/local/cuda/doc/CUDA_Profiler_2.3.txtに書かれている内容の日本語抜粋だと思ってくれればOK。


必要な知識

環境変数の設定方法。

bashならexport HOGE=FUGA、tcshならsetenv HOGE FUGA。詳しくはググれ。


実際の使い方

  1. 環境変数CUDA_PROFILEに1を設定する。
  2. 必要に応じて環境変数CUDA_PROFILE_LOGにプロファイル出力先を設定する。設定しなければカレントディレクトリの./cuda_profile.log.に出力される。複数GPUの場合は%dとかで制御できる模様。
  3. 必要に応じて環境変数CUDA_PROFILE_CSVを設定する。1にするか0にするかで出力ファイルの書式が変わる。取り込んで使うときはお好みのものを使いましょう。
  4. 環境変数CUDA_PROFILE_CONFIGに設定ファイルのパスを指定する。この設定ファイルに書かれている項目のプロファイル情報が、前述の出力先ファイルに吐かれることになる。

CUDA_PROFILE_CONFIGで指定した設定ファイルには、プロファイル項目を改行区切りで並べておけば良い。ただし、最大4つしか指定できない。(後者のカーネル実行カウンタが4つで、前者のオプションは全部OKかも?)

  • オプション
    • timestamp : カーネルの実行やデータ転送の時刻。(単位はなんだろう?)
    • gridsize : GridあたりのBlock数
    • threadblocksize : BlockあたりのThread数
    • dynsmemperblock : 動的に確保された、BlockあたりのSharedMemoryの大きさ
    • stasmemperblock : 静的に確保された、BlockあたりのSharedMemoryの大きさ
    • regperthread : Threadあたりのレジスタ使用数
    • memtransferdir : メモリ転送の方向、0だとホストからGPU、1だとGPUからCPU
    • memtransfersize : メモリコピーのバイト数
    • streamid : ストリームのID
  • カーネル実行カウンタ
    • gld_incoherent : コアレスドでないGlobalMemory読み込みの回数
    • gld_coherent : コアレスドなGlobalMemory読み込みの回数
    • gld_32b : 32byte単位のGlobalMemory読み込み回数
    • gld_64b : 64byte単位のGlobalMemory読み込み回数
    • gld_128b : 128byte単位のGlobalMemory読み込み回数
    • gld_request : GlobalMemory読み込み回数
    • gst_incoherent : コアレスドでないGlobalMemory書き込み回数
    • gst_coherent : コアレスドなGlobalMemory書き込み回数
    • gst_32b : 32byte単位のGlobalMemory書き込み回数
    • gst_64b : 64byte単位のGlobalMemory書き込み回数
    • gst_128b : 128byte単位のGlobalMemory書き込み回数
    • gst_request : GlobalMemory書き込み回数–local_load : LocalMemory読み込み回数
    • local_store : LocalMemory書き込み回数
    • branch : Threadあたりの分岐回数
    • divergent_branch : Threadあたりのdivergentな分岐回数
    • instructions : 実行された命令数
    • warp_serialize : SharedMemoryやConstantMemoryのアドレスコンフリクトによりwarpがシリアライズされた回数
    • cta_launched : Threadが実行された回数

ちょっと翻訳を勘違いしているのとかあったらごめんなさい。あと、めんどくさくて実行確認してませんごめんなさい(酷い

tgbt GPU・GPGPU関連

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加


NVIDIAの新GPUがかなりがんばってる件

10月 3rd, 2009

y㓡O΂WeeklyCOj[Xz NVIDIAGPUA[LeN`uFermiv𔭕\

NVIDIA GPU Technology ConferenceF͑sȃRs[eBOv̎n܂ɉ߂Ȃ (1/3) – ITmedia +D PC USER


Fermiが発表された.性能が倍になったとかいうのは十分に想定の範囲だとして,アーキテクチャの変更が結構すごいと思った.

CUDAが発表されて製品が出始めた頃に,「CUDAというアーキテクチャを出してきたのはいいけど,これっていつまでもつんだ?GPUの世代交代で崩れたりしない?」とか思ったり話したりしたんだけど,今回のFermiがいきなりがんばりすぎてると思う.

  • プロセッサの数の割り振り方ーつまりStreamingMultiprocessor(SM)あたりのプロセッサ(今までの用語ではSP,今回からはCUDA core)数が8から32に増えた
  • SMごとに持つ共有メモリのサイズが16KBから64KBに増えた(SMあたりSP数が4倍になったので妥当だけど)

この辺の数字はチューニングの面ですげえ重要な値だった.今後,単純に増やせばいいのかというときっとそうでもない.なんせ真の実行単位であるWARPのスレッド数が32のままだから……って,あれ?今まではSP数8にWARP32だから4命令ごとに考えるチューニングが必要だったんだけど,Fermiは32の32だからまとめて考える必要が無い……???

ま,これは実際に製品が出る頃にガイドが出るのを待たないとわからないか.


他に気になる変化としては,

  • メモリアドレスの管理方法がフラットになった
  • スレッドエンジンの拡張によってカーネル実行が柔軟になった

なんてのがある.

個人的にはこの辺が凄く気になっていて重要だと思っている.プログラムの最適化支援とかミドルウェア作成とかに興味がある身としては,凄くいじくり回したい.

それと同時に,今までとどう変わるのか,どう変えてコーディングする必要があるのかが不安で仕方がない.なにより,これでユーザ側に大きな変化が必要となると,さらに次の世代のCUDAでまた変わるんじゃないかという疑問・懸念・問題が出てくる.研究の種としては楽しいけど,実際アプリケーションを作って動かす側としてはツライよね.


OpenCLが出てGPGPUも少し固まってきたかなというイメージは一応あったけど,やっぱり水物だぁと再確認した.これを踏まえて研究計画練らないといかん.なんせ,半年頑張って新しい機能を作ったところで,ベンダーに「半年後のGPUではそれもっとスマートにネイティブサポートするよ」なんて言われたら面白くない.これだからGPUの研究は笑えないし楽しいんだぜ.

tgbt GPU・GPGPU関連

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加


CUDAと浮動小数点の誤差に関する実験メモ

8月 14th, 2009

「CUDAはIEEE754対応だよ!計算精度はCPUと変わらないよ!!!」みたいなことをこれまでに何度か聞いていたような気がするので,実際のところどうなのかを試してみた.これが直接的に論文のネタになるとは思っていないので,公開しておきます.


対象問題

誤差が出る問題として何を使うかちょっと悩んだんだけど,手元の数値計算の教科書(新版 入門数値計算)の最初に掲載されていた「ニュートン・ラフソン法」を実装してみることにした.

もはや授業を受けたときの頃は全然覚えていないんだけど, f(x) = x^3 -2x -5 = 0の実根alphaを求める という問題.「組み立て除法」ってのを使う.


ソースコード

難しいことは考えずに,ガツッと決め撃ちした.

void kernel(TYPE *rs, TYPE *ep)
{
  TYPE X3 = 1.0f;
  TYPE X2 = 0.0f;
  TYPE X1 = -2.0f;
  TYPE X0 = -5.0f;
  TYPE x3 = 0.0f;
  TYPE x2 = 0.0f;
  TYPE x1 = 0.0f;
  TYPE x0 = 0.0f;
  TYPE z0 = INIT;
  TYPE z = z0;
  TYPE a, b, c, d, e, f, g;
  int i;
  for(i=0; i<NLOOP; i++){
    x3 = X3;
    x2 = X2;
    x1 = X1;
    x0 = X0;

    a = x3;
    b = a * z;
    c = x2 + b;
    d = c * z;
    e = x1 + d;
    f = e * z;
    g = x0 + f;

    x3 = a;
    x2 = c;
    x1 = e;
    z = g;

    a = x3;
    b = a * z0;
    c = x2 + b;
    d = c * z0;
    e = x1 + d;

    rs[i] = z0 - z/e;
    ep[i] = (z/e)*(z/e);
    z0 = rs[i];
    z = z0;
  }
}

CPUもGPUも同じ計算カーネル.(GPUのカーネルにはもちろん__global__がつきますが.)

速度はどうでも良いし並列性もどうでも良い.Grid/Blockのパラメタも(1,1)(1,1,1)な設定でOK.

型TYPEはfloatとdoubleとを切り替えてコンパイルできるようにしている.初期値INITも入れ替えられるようにしておいた.


実行環境など

Core i7 + TeslaC1060.CentOS5.x x86_64.cudaのバージョンは2.21.-m 64で64bitのバイナリを吐かせている.doubleを使いたいので,もちろん-arch=sm_13.


実行結果

教科書では初期値2.0でやってたんだけど,収束の具合が見たいので適当に1.0にしてやってみた.ループ回数は特に考えも無しに適当に20回.

はじめにfloatでやった結果から.結果と誤差,それぞれ右下に行くほど繰り返し数が多い際の値.

結果:CPU 7.000000e+00 4.765517e+00 3.348703e+00 2.531600e+00 2.173916e+00 2.097884e+00 2.094558e+00 2.094552e+00 2.094551e+00 2.094552e+00 2.094551e+00 2.094552e+00 2.094551e+00 2.094552e+00 2.094551e+00 2.094552e+00 2.094551e+00 2.094552e+00 2.094551e+00 2.094552e+00

結果:GPU 7.000000e+00 4.765517e+00 3.348703e+00 2.531600e+00 2.173916e+00 2.097884e+00 2.094558e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00 2.094552e+00

誤差:CPU 3.600000e+01 4.992913e+00 2.007363e+00 6.676576e-01 1.279377e-01 5.780894e-03 1.106205e-05 3.943923e-11 1.642639e-14 4.562891e-14 1.642639e-14 4.562891e-14 1.642639e-14 4.562891e-14 1.642639e-14 4.562891e-14 1.642639e-14 4.562891e-14 1.642639e-14 4.562891e-14

誤差:GPU 3.600000e+01 4.992913e+00 2.007363e+00 6.676576e-01 1.279377e-01 5.780877e-03 1.106177e-05 3.784591e-11 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00

結果を見ると同じに見えるけど,実は途中で少しだけ値が変わってしまっている.

そして誤差を見るとGPUは途中から誤差が無くなってしまっている.なんだか変だ.


とはいえここまではfloat型.本番?はdouble型だよね.

結果:CPU 7.000000e+00 4.765517e+00 3.348703e+00 2.531600e+00 2.173916e+00 2.097884e+00 2.094558e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00

結果:GPU 7.000000e+00 4.765517e+00 3.348703e+00 2.531600e+00 2.173916e+00 2.097884e+00 2.094558e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00 2.094551e+00

誤差:CPU 3.600000e+01 4.992913e+00 2.007363e+00 6.676575e-01 1.279377e-01 5.780895e-03 1.106208e-05 3.886632e-11 4.787812e-22 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32 2.532912e-32

誤差:GPU 3.600000e+01 4.992913e+00 2.007363e+00 6.676575e-01 1.279377e-01 5.780895e-03 1.106208e-05 3.886632e-11 4.787810e-22 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33 3.447355e-33

計算結果を見る限りではCPUとGPUの差は見受けられなかった.でも誤差を見ると違いがある.

なんだろうね,これ.

考察

というわけでして,CPUとGPUでは(double型で計算しても)実行結果に差が生じた.

原因はちょっとまだわかっていない.レジスタの違い?

そもそも,こうやって計算結果(誤差計算結果)の違いを見てしまうと,使い方が悪いだけなのか(GPUには問題はないのか)という疑問が生じるところ.実はGPUもちゃんとIEEE754には対応していて,CPUはさらに高精度な計算をしている?それはちょっとおかしいよねえ.


まぁとりあえずこんなところで.

数値計算に詳しい人に聞いてみるか,何も考えずにNVIDIAのForumに投げ込むか.でもForumに投げ込むにはちょっと問題(ソースコード)がシンプルじゃないしなあ.もっとプリミティブな例を作成してみようかしら?

tgbt GPU・GPGPU関連

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加


WindowServer2008でマルチユーザCUDA?

8月 11th, 2009

WindowsServer(2008)はマルチユーザ、複数人で同時使用可能なWindows、こいつにTeslaをさせば、複数人で共有できるんじゃねえ?


そう考えていた時期が、私にもありました。

確かにServer2008にVistaのドライバをぶち込んだらCUDAは動きました。


さて問題はマルチユーザ。WindowsServer2008のマルチユーザはリモートデスクトップで成立している。複数人で同時にリモートデスクトップする。

しかし、TeslaをたたくにはNVIDIAのドライバが必要。現状のWindows向けNVIDIAドライバはグラフィックスと一体化状態。リモートデスクトップを使うとディスプレイドライバは専用のモノが使われる。NVIDIAのドライバが読み込まれない。


うん、駄目だこれ。

モノは試しとばかりにVNCも試してみたけど、やっぱり駄目だった。ユーザがログインした状態で放置しておいてVNC接続をすれば、確かにリモートでCUDAがたたける。でもログアウト(ユーザの切り替え)をしちゃうと使えない。

#ちなみにこの症状はXPやVistaでも同じはず。



んー、複数のWindowsユーザがTeslaを共有できればいろいろと便利な気がするんだけど、ちょっと難しいなあ。

ちなみに、いわゆるバッチキューシステムみたいなのを構築しちゃえばなんとかなるのはほぼ自明。バッチ処理するユーザが常にログインしてNVIDIAのドライバを読み込んでおけば良い。用途によってはもちろんそれでいいんだろうなぁ。

tgbt GPU・GPGPU関連

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加


CUDA 2.3のメモ

7月 27th, 2009

ToolkitとSDKの2.3が出たので,リリースノートを読んだメモを残しておく.

リリースノートをちゃんと読むのは久しぶりだったりする.酷い話だ.


ちなみに,これを書いている現在では,nvidia.co.jpには2.3のダウンロードはありません.おとなしくnvidia.comへ行きましょう.


toolkit 2.3

(http://developer.download.nvidia.com/compute/cuda/2_3/toolkit/docs/cudatoolkit_release_notes_windows.txt)

New Features(新しい機能)
  • Win7サポート(32bit/64bit)
  • CUFFTの性能向上と倍精度計算サポート

これって,倍精度非対応のGPUで動かそうとしたらどうなるんだろう?

  • 64bitPCでの32bitアプリ作成対応

先日ひっかかった記憶があるなこれ.入れ直して試してみよう.

  • SLI DeviceEmulationの強化

今まで何ができなかったのかを把握していないのと,該当する環境を使用していないのでスルーで.

  • コンパイラによる倍精度の扱いの変更?

いままでは,sm_13より古いバージョン指定の場合に出力されるptxは倍精度の記述を単精度に勝手に落として使っていて,warningを出していた.新しいオプションをつけることで抑制可能になった.

Major Bug Fixes(バグ修正)
  • DeviceEmulationにおけるC++の対応の修正

DeviceEmulationについて「Support is restored for …」って書いてある.一度対応させたけどバギーだったので封印して,改めて対応したのかな?

Known Issues(既知の問題) Vista/Server2008向け
  • PhysX実行時の制限?

In order to run CUDA on a non-TESLA GPU, either the Windows desktop must be extended onto the GPU, or the GPU must be selected as the PhysX GPU.

なんだこりゃ?TESLAじゃないGPUでCUDAを実行するためには,Windowsのデスクトップ出力先がそのGPUであってなおかつPhysXの対象GPUになってないといけないってことか?

  • GPUカーネル実行時間制限

2秒までよ.

  • cudaMallocやcuMemAllocで確保できるメモリサイズの上限

MIN ( ( System Memory Size in MB – 512 MB ) / 2, PAGING_BUFFER_SEGMENT_SIZE ),VistaだとPAGING_BUFFER_SEGMENT_SIZEが2GB

ええと,1GBのメモリを搭載している場合は(1024-512)/2=256MB,2GBだと(2048-512)/2=768MB,4GBでも1792MBか.……マジ?

Known Issues(既知の問題) XP向け
  • 5秒制限
Known Issues(既知の問題) XP/Vista向け
  • 複数GPU環境でのGPU列挙の順序は不定

しかも,今後変わるかも知れないよ!とのこと.性能確認して一番速そうなのを使うってのがサンプルにあった気がするなあ.

  • メモリ使いすぎの際の注意

CUDA_ERROR_OUT_OF_MEMORYが出るとコンテキストが使用不能になる

  • OSのバグでMallocが死ぬかも

http://support.microsoft.com/kb/940105

  • vector_types.h問題

32bitWinでvector_types.hを使う場合,16byteアラインメントのベクタが腐るよ.

  • cudaThreadExit問題

cudaThreadExitは暗黙に呼ばれないことがあるよ.明示的に呼んでね.

  • ?

ええと,union使ったときとかに良くないメモリアクセスが起きるかも.今後コンパイラが改善できるといいな,とか書いてある.

  • OpenGL関係

割愛


cudasdk 2.3

名称変更

NVIDIA CUDA SDK から NVIDIA GPU Computing SDK へ.なん…だ…と…!?また紛らわしくなるなぁ.

PTXJIT追加

cuModuleLoadDataExサンプルの追加.ファイルからではなくメモリ上のイメージ(?)からPTXを読めるようになる.これはいずれ作る必要があると思っていた機能なのでうれしい.

cudaDecodeD3D9とcudaOpenGLの追加

よくわからないが,ビデオのデコード関係.Cudaで高速デコードしてくれるのかしら???


だいたいこんなかんじ(ギャグマンガ日和のリズムで).


ここまでの内容は,nvidiaの日本語のフォーラムにも書いてあったりする.ちょっと違うことが書いてある気もするけど…….


それから,本家のフォーラムにも記述がある.これによると,デバッガやプロファイラがToolkitと一緒にインストールされるようになったらしい.これから試す!

あと,CUDA C Best Practices Guide 2.3というドキュメントも増えたので,これから目を通すよ!

tgbt GPU・GPGPU関連

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加