Slide 1

Slide 1 text

GPU Hash Table #rtcamp10 Nishiki @yknishidate

Slide 2

Slide 2 text

01. Hash tableについて ・一意のKeyとValueの形式でデータを保存する ・KeyをHash関数でHash値(≒インデックス)に変換 ・O(1)で挿入、検索、(削除)できる(はず) ・Hash値は衝突する可能性がある https://khalilstemmler.com/blogs/data-structures-algorithms/hash-tables/ 2

Slide 3

Slide 3 text

01. Hash tableについて Hash grid ・CGでは空間をグリッドで分割することがよくある ・解像度^3のメモリは巨大すぎるので、スパースである  場合は必要なセルだけをHashで圧縮して格納するといい ・これをHash grid, Grid hashing, Spatial hashingと呼ぶ ・近傍探索や衝突検出で広く使われる ・レンダリングでもPhoton mappingやPath guiding、  Irradiance cacheなどで使われる ・境界がないグリッドで使うこともできる Fuentes, Joel & Luo, Fei. (2018). Synchronizing Parallel Geometric Algorithms on Multi-Core Machines. 3

Slide 4

Slide 4 text

01. Hash tableについて 設計は目的によって大きく異なる ・必要な操作は?(挿入・検索・削除) ・挿入と検索はどちらを高速にすべき? ・どのHash関数を使う? ・Hash衝突をどう扱う? ・データはdynamic? ・テーブルサイズはdynamic? ・どの程度圧縮する? ・隣接セルにアクセスする? ・キャッシュ、空間的コヒーレンス? ・適応的解像度が必要? ・安定性があるべき? ・GPU並列化? 本スライドでは... ・おおむねGPU上のHash gridを目的とする ・特定の手法を解説するのではなく、いくつかの  設計要素についてアラカルト的にテクニックを紹介 4

Slide 5

Slide 5 text

02. ハッシュ関数 ハッシュ関数はめちゃくちゃ色々あるが、3D hash gridの場合以下がよく使われる M. Teschner, B. Heidelberger, M. Mueller, D. Pomeranets, M. Gross, “Optimized Spatial Hashing for Collision Detection of Deformable Objects,” Matthias Müller, “Finding collisions among thousands of objects blazing fast” ・mod高速化:n=2^k なら x % n を x & (N-1) に高速化できる 5

Slide 6

Slide 6 text

03. 衝突の処理 ハッシュの衝突 ・ハッシュ関数は異なるKeyに対して同じ  ハッシュ値を出力することがある ・こうなるとテーブルの同じスロットに  複数のデータを格納しようとするので困る https://en.wikipedia.org/wiki/Hash_collision 6

Slide 7

Slide 7 text

03. 衝突の処理 チェイン法 ・スロットにリストを持たせる ・衝突したらリストを伸ばす ・👎リストの扱いがメモリ的にだるい ・👎リスト内は線形探索が必要 オープンアドレス法 ・衝突したら次の空きスロットを探して入れる ・👍メモリ上連続 ・👎線形探索が必要 ※probingにもいろいろある:linear, quadratic, double hashing https://en.wikipedia.org/wiki/Hash_table https://en.wikipedia.org/wiki/Open_addressing 7

Slide 8

Slide 8 text

03. 衝突の処理 Cuckoo hashing(オープンアドレス系) ・2つのハッシュ関数(h1, h2)と2つのテーブル(T1, T2)を用いる ・挿入時に衝突が起きたら、古いデータを追い出す ・xの挿入を試みる ・T1[h1(x)]が空いてたら入れて終了 Cuckoo Hashing - Radium Software https://kzr-2.hatenadiary.org/entry/20080531/p2 8

Slide 9

Slide 9 text

03. 衝突の処理 すでにyで埋まっていた場合... ・xを無理やり入れてyを取り出す(swap) ・yはT2[h2(y)]に移動する Cuckoo hashing(オープンアドレス系) ・2つのハッシュ関数(h1, h2)と2つのテーブル(T1, T2)を用いる ・挿入時に衝突が起きたら、古いデータを追い出す Cuckoo Hashing - Radium Software https://kzr-2.hatenadiary.org/entry/20080531/p2 9

Slide 10

Slide 10 text

03. 衝突の処理 Cuckoo Hashing - Radium Software https://kzr-2.hatenadiary.org/entry/20080531/p2 yの移動先がzで埋まっていた場合... ・yを無理やり入れてzを取り出す ・zはT1[h1(y)]に移動する Cuckoo hashing(オープンアドレス系) ・2つのハッシュ関数(h1, h2)と2つのテーブル(T1, T2)を用いる ・挿入時に衝突が起きたら、古いデータを追い出す →これを繰り返していく 10

Slide 11

Slide 11 text

03. 衝突の処理 Cuckoo hashing(オープンアドレス系) ・2つのハッシュ関数と2つのテーブルを用いる ・挿入時に衝突が起きたら、古いデータを追い出す ・👍必ず2回のアクセスで検索が完了する!   xはT1[h1(x)]かT2[h2(x)]のどちらかに必ず格納される ・👎挿入時が大変、無限ループする危険すらある ・👎安定でない(要素の格納位置が勝手に変わる) → とにかく検索を高速にしたいなら有用   ここ数年でもGPU実装の発展手法が提案されている 11

Slide 12

Slide 12 text

03. 衝突の処理 Iceberg hashing(ハイブリッド系) ・hash値は個別のスロットではなく、  あるサイズをもったバケットを指定する  ※他の手法でもよく使われる。キャッシュによかったり ・3レベルのバケットと3つのハッシュ関数  (h0, h1, h2)を組み合わせる Prashant Pandey, Michael A. Bender, Alex Conway, Martin Farach-Colton, William Kuszmaul, Guido Tagliavini, and Rob Johnson. 2022. IcebergHT: High Performance Hash Tables Through Stability and Low Associativity. ・h0(x)を計算し、Level1バケットが空いていれば格納 ・Level1 が満杯であれば、h1とh2でLevel2バケットを  2つ選び、より空いている方に格納(偏りが減る) ・Level2 バケットが両方とも満杯であれば  チェイン法によるLevel3バケットに格納 12

Slide 13

Slide 13 text

03. 衝突の処理 Iceberg hashing(ハイブリッド系) ・hash値は個別のスロットではなく、  あるサイズをもったバケットを指定する  ※他の手法でもよく使われる。キャッシュによかったり ・3レベルのバケットと3つのハッシュ関数  (h0, h1, h2)を組み合わせる ・👍安定(データは勝手に移動しない) ・👍平均バケットアクセス回数が少ない ・👌チェイン法は苦しいが、Level3の使用は非常にレア   ※別にLevel3をチェイン法以外にしてもOK → GPU実装でもアリとされている Prashant Pandey, Michael A. Bender, Alex Conway, Martin Farach-Colton, William Kuszmaul, Guido Tagliavini, and Rob Johnson. 2023. IcebergHT: High Performance Hash Tables Through Stability and Low Associativity. ・h0(x)を計算し、Level1バケットが空いていれば格納 ・Level1 が満杯であれば、h1とh2でLevel2バケットを  2つ選び、より空いている方に格納 ・Level2 バケットが両方とも満杯であれば  チェイン法によるLevel3バケットに格納 13

Slide 14

Slide 14 text

03. 衝突の処理 衝突させない!(Perfect spatical hashing) ・静的データを衝突なしで圧縮する Sylvain Lefebvre and Hugues Hoppe. 2006. Perfect spatial hashing. ※128^3 = 200万 ※128^2 = 1.6万 14

Slide 15

Slide 15 text

03. 衝突の処理 衝突させない!(Perfect spatical hashing) ・静的データを衝突なしで圧縮する ・2つの適当なハッシュ関数 (h0, h1) と  オフセットテーブル Φ を組み合わせる Sylvain Lefebvre and Hugues Hoppe. 2006. Perfect spatial hashing. 15

Slide 16

Slide 16 text

03. 衝突の処理 衝突させない!(Perfect spatical hashing) ・静的データを衝突なしで圧縮する ・2つの適当なハッシュ関数 (h0, h1) と  オフセットテーブル Φ を組み合わせる ・H内で起きる衝突を回避させるような  オフセット(移動)を計算しておく Sylvain Lefebvre and Hugues Hoppe. 2006. Perfect spatial hashing. ・オフセットテーブルの要素は複数のピクセルに対する移動を表現 ・これを衝突を回避するような移動になるよう最適化する ・最初は十分大きなオフセットテーブルから始めて、  Perfectを満たせる限度までテーブル小さくしていく 16

Slide 17

Slide 17 text

03. 衝突の処理 衝突させない!(Perfect spatical hashing) ・静的データを衝突なしで圧縮する ・2つの適当なハッシュ関数 (h0, h1) と  オフセットテーブル Φ を組み合わせる ・H内で起きる衝突を回避させるような  オフセット(移動)を計算しておく ・👍衝突なしなので1回でアクセスできる ・👍データをほぼ最小まで圧縮できる ・👎対象は静的データに限られる(事前計算が必要) Sylvain Lefebvre and Hugues Hoppe. 2006. Perfect spatial hashing. 17

Slide 18

Slide 18 text

03. 衝突の処理 衝突を気にしない! ・目的によっては別に衝突してもいい ・例:パーティクル同士の衝突判定 ・👍ある意味最強 Matthias Müller, “Finding collisions among thousands of objects blazing fast” Hash gridで近傍探索した後にパーティクル同士の衝突判定をする → 衝突しても余計なパーティクル衝突判定が   走るだけで、判定結果は変わらない 18

Slide 19

Slide 19 text

04. キャッシュ&空間的コヒーレンス キャッシュを考慮するといい ・バケットサイズ = キャッシュラインサイズ にする 隣接セルにアクセスするならコヒーレンスを高める ・緩和クラスタリング Pascal Gautron. 2022. Advances in Spatial Hashing: A Pragmatic Approach towards Robust, Real-time Light Transport Simulation. ・2x2x2=8セルを1クラスタとして、まとめて配置する ・ただ、それだと8セルの中で使わなかったセルがメモリを浪費... ・クラスタをオーバーラップさせて配置する ・コヒーレンスを高めつつメモリを削減できる 19

Slide 20

Slide 20 text

05. Warpの活用 前提:オープンアドレス法 単一スレッド=単一データで処理する場合、 線形探索が必要になる NVIDIA, Maximizing Performance with Massively Parallel Hash Maps on GPUs. https://developer.nvidia.com/blog/maximizing-performance-with-massively-parallel-hash-maps-on-gpus/ Daniel Junger et al., WarpDrive: Massively Parallel Hashing on Multi-GPU Nodes Warp内の複数スレッドで単一データを処理させれば、 ballotで最初の空きスロットを1発で見つけられる 20

Slide 21

Slide 21 text

06. アンチエイリアス Irradiance cacheとかで使う場合、 セル境界とメッシュがぴったり重なると Z-fighting的なちらつきが起こることがある Pascal Gautron. 2022. Advances in Spatial Hashing: A Pragmatic Approach towards Robust, Real-time Light Transport Simulation. 位置を周期関数でセルを歪ませることで ちらつきを抑えることができる 21

Slide 22

Slide 22 text

07. おまけ その他の提案されているGPU Hash Table ・Slab hash(チェイン系) ・Hopscotch on GPU(オープンアドレス系) ・Stadium hashing 現役のCUDAハッシュマップライブラリ ・cuCollections by NVIDIA  ・cuco::static_map  ・cuco::static_multimap  ・cuco::dynamic_map Vulkanと動的テーブルの話 シェーダ側でバッファアドレスを使って ポインタ的操作ができるようになった → ランタイムでバッファを確保・追加し、   アドレス配列にアドレスを書き込むだけで、   バインディング更新なしでシェーダで動的テーブルを扱える p0 p1 p2 Buffer0 Buffer1 Buffer2 22