CeriumにおけるGPGPUの最適化 |
Yuhi TOMARI
|
当研究室ではCellおよびLinux、 Mac OSX上で動く並列プログラミングフレームワーク、 Ceriumの開発・改良を行っている。
本研究では新たにGPU上での並列実行に対応し、 ヘテロジニアス(異種混合)環境下でのプログラミングをサポートする
GPGPUでは通常のマルチコアCPUとは異なる並列プログラミング と特別なチューニングが必要となる。 そこでCeriumを用いてその差を吸収し、自動的なチューニングを可能にする。
しかし、GPUのみで並列計算を行った場合、Taskによっては並列度が出ない場合がある。 そこでチューニングの一環として、MultiCoreとGPU上での同時実行を可能にする。
void *malloc(size_t size);
char *str = (char*)malloc(length); // 使う型でキャストする
union header { struct { union header *ptr; // 空きリストの上なら次のブロック unsigned size; // このブロックの大きさ } s; };
リストを頭から見ていって、最初に見つけたものを使用するというすごいシンプルな方法。
実は、もう一個先にもっと適切なブロックがあった。こんな場合に対応できない…というか、対応しないのがfirst fit。
あまりよくない……
void free(void *ptr);
メモリの開放自体は、使用中のブロックをfree listに追加するだけで良い。 引数で受け取ったポインタ部分を開放したら良い……かに思える。 でもそれだけじゃダメで、開放したい領域と隣接しているブロックが空きブロックなら併合しないといけない。
listから最初のポインタと、その次のポインタを取得。prev < p < nextを満たすまで走査していく
あった!!
開放後に前後のメモリと併合する必要がある場合があるので、prevとp・pとnextが隣接してるか判定する。
ブロックが隣接している場合は併合する。
チェックに引っかかったところをマージする。
フラグメンテーションが頻発する。
そもそも、一つのfree listで管理することが無理がある
サイズ16Byte用のリスト、サイズ24Byte用のリスト……というようにリストを複数作ってやる
|
---|
void *alloc_mmap(size_t size) { int fd = open("/dev/zero", O_RDONLY); void *ret = mmap(addr, length, prot, flags, fd, offset); return ret; }
addr | mapするメモリアドレス。NULLを渡せばkernelがアドレスを選択する。 |
---|---|
length | addrから何バイトマッピングするか。 |
prot | マッピングのメモリ保護の指定。Read Write Exec None等がある。 |
flags | マップを要求された時、共有するかコピーを渡すか。 |
offset | ファイルの何バイト目からをメモリにマップするか。 |
mmapで確保するので、free listからは独立している。
listを使って管理しているわけではないので、listをたどったりしなくて良い。 ほしかったらmmapして、いらなくなったらmunmapすればよい。 |
---|