2011年6月26日日曜日

6/26 時間測定

今まで何も考えていなかったが、Windows環境での時間測定のやり方がわからない。
gettimeofdayが使えないだけでこれだけ苦労するとは・・・。

QueryPerformanceCounterやtimeGetTimeを使おうとしたのだが、
ぜんぜんうまくいかない・・・。

何が起こっているのかよくわからないが、今日中に終わらせるのは無理ということだけは確実だ。
諦めて明日誰かに聞く。

6/26

今までのバグの原因が判明した。
OpenCLカーネル内で、片方のスレッドがもう片方のスレッドの結果を上書きしていた模様。
これにより、実行の順番によって結果が変動していたようだ。
GPUのときに失敗しなかったのは、単純に運がよかっただけのようだ。

とにかく、これでバグは全部ないはずなのでベンチマークができる状態に仕上げなければ。

2011年6月24日金曜日

6/24 謎の挙動

スレッドの同期か何かの問題と思うのだが、CPU実行すると計算結果が2パターン現れる。
APUのほうでは十数回実行しても全く変化がなかった。何故だろう。

APU実行 正しい結果(計算の誤差は大きい模様)


CPU実行 正しい結果


CPU実行 誤った結果


この問題さえどうにかなれば、後は数十~数百スレッドで実行時間を測定すればよい。
先はまだまだが、どうにかなりそうにはなってきた。


bi(bargain index)に-0と-expがあるが、これはvwapとask_priceの関係によって式が2種類あるため。
どちらの分岐に入ったかを検知するために付与している。


APU(GPU)は演算器の実装が違うのか誤差が出やすい模様。
今後、この点にも注意する必要がありそう。

6/24 OpenCL Debug

とうとうOpenCLでVWAP計算が動作した。
しかしながら、まだシングルスレッドで一周のみの動作しかさせていないので、
複数スレッドで連続計算できるように改修が必要だ。
カーネル関数自体の動作は確認できたので、作業はだいぶ楽になった。

OpenCLのDebugではFermi以降のCUDAと同様kernel関数内部でのprintfが使える。
書式はC/C++と同様で、文字列なども難なく扱える。
表示が実際に行われるタイミングは非同期のようだが、同期を行えば確実に表示できる。
clWaitForEvents関数がそれで、第一引数に待ちイベント数、第二引数にイベント配列を渡す。
イベント配列はカーネル関数実行時やメモリ読み書き時に指定できるので、
カーネル関数実行時に設定したイベントをこの関数に渡してやればよい。

・OpenCL 1.1のKhronos公式のリファレンス
知りたい関数などを一発で検索できるため大変便利
http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/

2011年6月17日金曜日

6/17

OpenCLのカーネルビルド時のエラーの詳細を見るための関数があるようだ。

 clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);

これで作業が少しは楽になりそう。

しかし、これを知ったのがBuild Errorを解決してからだった。ショック。
しかも、今度はNDRangeKernelの起動でエラーが。

先は長そうだ。

6/17 OpenCL kernel関数の罠

*今回の教訓
ドキュメントは隅々までちゃんと読むべし


OpenCLでは実行時にカーネルソースを読み込み、JITコンパイルする。
このカーネルソースのファイルへの思い込みのせいで1週間以上を無為に過ごしてしまった。


1.カーネルソース内では#includeできない
#PROGRAM_BUILD_FAILURE(-11)で盛大にこけます

2.カーネルソース内のカーネル関数には二重ポインタは渡せない
#同上でこけます
#そもそも今考えるとどうして二重ポインタを渡そうとしていたのかが謎

3.カーネルソース内ではC++のように好きなところで変数宣言はできない
#同上
#ちゃんと先頭で全て定義しましょう


以上を踏まえて書き直したところ、あっさりコンパイルが通って虚脱した。
心が折れそうだ。

2011年6月16日木曜日

6/16 Fusion

AMDもAシリーズ(Llano世代)からようやく本気を出すらしい。
APUによるGPGPUを後押しするためのソフトウェア層の再定義を行うらしい。
中間言語レイヤでCPUやGPUとOpenCLやC++ AMPとの隙間を抽象化する。
これらはすぐに出てくるのかどうかは微妙。

APUのアーキテクチャ自体も、CPUとの協調を重視した設計のようだ。
GPUからメモリへのバスが、メモリコントローラへの直結側と、
CPUとのコヒーレンシを保てるバスの二つになっている。
これにより、グラフィックス性能とGPGPU性能を両立できるようだ。
名前がGarlicバスとOnionバスのようだが、もう少しまともな名前にできなかったのだろうか。

OpenCLのデバッグ環境も、OpenCLのカーネルコードをC++のプロシージャとして扱えるものが出た。
今ドキュメントを読んでいる途中なので詳しいことはわからないが、使えるかもしれない。

2011年6月15日水曜日

6/14

昨日先生にミーティングをしていただき、研究の方針を定めることができた。
後は実装結果を元に知見をまとめればよいのだが、OpenCL+APUは未知の領域が多く、
OpenCL関連の実装経験も情報も乏しいためなかなか作業が思うように進まない。

今日は家で作業を進めるはずが、自室の照明が突然死して大いに困った。
回路を調べてみると、インバータのコンデンサが自壊し穴が開いていた。
ヒューズは飛んでいないので、どこかのトランジスタが悪さをした模様。
一昨日も浴室の電球が切れたばかりで、不思議とこういうことは重なるものだと思った。

2011年6月10日金曜日

6/10

clEnqueue[Read|Write]BufferとclEnqueue[Map|Unmap]Bufferは最初の理解でよかった模様。
細かい値を引くなら前者、行列のようにランダムアクセスなどが発生する巨大な配列は後者を使えばよさそう。
昨日修正した部分はむちゃくちゃになっていたので再修正が入りそう。

2011年6月9日木曜日

6/9

今まで勘違いしていたが、OpenCLのNDRangeは1-3次元構造が3重に入れ子になった構造だった。
各階層の識別子は外側からワークグループID、ワークアイテムID、ローカルIDとなっている。
グローバルIDが知りたい場合、プログラム内で各IDから求める必要がある。面倒。

clEnqueueMapBufferとclEnqueueReadBufferも謎。
排他的に使うものなのかどうかよくわからなくなってきた。
今まで細かい部分を無視して適当にやってきたツケが回ってきたようだ。

6/9 OpenCLのコードをVC++で色つきに

Visual C++ 2010でOpenCLの開発をしているのだが、ソースが無色で非常に見づらい。
これを解決するには、
[ツール]→[オプション]→[テキストエディタ]→[ファイル拡張子]の項目に「cl」という拡張子を追加する。
このとき、デフォルトではVBになってる部分をちゃんとVC++にするように。

これだけではC++的な部分しか反映を受けないので、OpenCL特有の情報を教えてやる必要がある。
C:\Users\<ユーザ名>\Documents\AMD APP\samples\opencl\SyntaxHighlightingに、
usertype.datというファイルがあるので、これを
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
に放り込む。

Windows 7 AMD64 + Visual C++ 2010 + AMD APP SDK 2.4の組み合わせだが、
他の環境の組み合わせでもだいたい同じような作業を行えばうまくいくはず。
これもCUDA向けの情報から類推した結果なので。

参考URL:http://wiki.livedoor.jp/mikk_ni3_92/d/CUDA%CA%D400

2011年6月2日木曜日

6/2

ニートの危機を脱することができた。

研究室のノードの生存状況を1時間ごとに告知するShell Scriptを作成。
estherの/home/share/live.txtが出力ファイル。

本当はこのファイルからさらに見やすいHTMLを作成し、
世界中どこからでも研究室の状況がわかるようにしたかったのだが、
Webサーバを立ち上げるのは怖いし、クラウドで使えそうなサービスもなかったので断念。

GoogleサイトやGoogle Docsは機能が制限されているし、
Google App Engineに登録する気にはならないし悩ましい。