C

概要

  • GPGPUのプログラムの書き方
  • 最適化されたGPUは、最適化されたCPUの2倍程度の早さ
    • CUDAなら100倍!!とか言ってる人を見かけたら、「それCPUのほうも最適化したらどうなるんですか?」と聞いてあげるようにしましょう。
    • 本気じゃないなら、「簡単に書けて早い」「コーディング時間少なく早い」という程度に思っているべき

GPUの速度

  • Core i7は100GFLops
  • GeForce? 285は1000GFlops(この性能は1997年のスパコンレベル、なお2009年は131TFlops)
  • 8コアCore i7(第四世代2013年6月)は単精768GFlops, GeForce? GTX Titan Z(2014年4月)は単精度8121GFlops
  • 例えば粒子計算はいい加減実装でも1000倍早い。
  • 1.2はfloatのみ、1.3(GT200以降)からはdoubleが扱える
  • CPUとGPUは並列に処理可能(例外はcudaMemcpy)
  • cudaMemcpy
    • CPU->GPU, GPU->CPU, GPU->GPUのデータコピー
  • cudaMemcpyAsync?:非同期転送は現状効率が悪く、デバイスドライバの改良が待たれる
  • nvccはエミュレーション機能がある
    • 数千スレッドを立ち上げるのでハングアップしたように感じる。速度は1/1000以下になる。低問題サイズで行うべき
    • エミュレーションではprintfが使えるようになる。#ifdef __DEVICE_EMULATION__を活用
    • メモリ関係のデバッグは不能
  • カーネル関数のエラー検知はほぼ不可能
  • CUDA APIはcudaError_tで検知し、cudaGetErrorString?で詳細。cudaGetLastError?で最終エラー検知
  • dim3のデフォルトはx=y=z=1
  • GPUの特徴
    • カーネル関数はSPMD、各SMの中の8個のSPはSIMD
    • CPUにあってGPUに無いもの:Out-of-Order, 分岐予測, if文
  • メモリの種類
    • ローカル・グローバルメモリは100倍遅い(それでも159GB/s。CPUは36GB/s)
    • レジスタ:変数の数によって増減、32が上限なので無駄な変数は削減せよ
    • シェアードメモリ:高速
  • 性能評価
    • Occupacy 100%は良い事。
    • Active Thread Blocks per Multiprocessorが重要
    • SMあがり3ブロックがアクティブになると強い
  • SPUによる計算はちょっと精度が低い

TensorFlowの対応GPU

  • 3.5
名前価格(円)GFlops
GT 7205500306
GT 7306000692.7
GTX 780640003976.7
GTX 780 Ti900005045.7
GTX TITAN Z4000008121.6
GTX TITAN Black5120.6
GTX TITAN4499.7
  • 5.2
名前価格(円)GFlops
GTX 980 Ti850005632
GTX 980700004612
GTX 970400003494
GTX 960240002308
GTX 950185001573
GTX TITAN X130000

環境構築

  • NVIDIA GTX 960
    • Compute CapabilityがTensor Flow for GPUに適合していたため
  • Ubuntu 14.04.3

CUDA

  • CUDA 7.5
  • CUDAインストールは,パソコンが起動しなくなるリスクがある.重要な情報は必ず退避せよ
    • Ubuntuだと,Ubuntuの下に丸が5点ついた状態で止まる.何回かリセットしているとCUIで起動することもある.
  • debパッケージで入れること&初心者は計算専用GPUを作りたいとか言っていないで,まずはGPGPUすることを目標とすること
    • runファイルは何故か動かなかった.debで入れること!(ArrayFire?はdeb推奨)
    • GPGPU+描画用を分けるにしても,NVIDIA+NVIDIAとメーカは揃えたほうがいい.
    • 間違っても,作業中にsudo aptitude install nvidia-340-devなんて打たないこと.ドライババージョンが変わって,何も動かなくなる
  • インストール手順(必ず公式ガイドを参照)
    • 重要な事前知識
      • NVIDIA Driverはデフォルトのnouveauと競合してカーネルパニックを起こして起動しなくなる→nouveauを切ってCUIモードで作業必須
      • runではなくdebが推奨(ArrayFire?などもそう言ってる)
    1. 必要なデータ退避
    2. GPU刺す(外部電源あり.電源逆刺しに注意)
    3. 起動
    4. CUDA 7.5のdebをダウンロードし,~/に置く
    5. lspci | grep -i nvidia # GPU認識されていること確認
    6. /etc/modprobe.d/blacklist-nouveau.confを作成,以下を入れる.
      blacklist nouveau 
      options nouveau modeset
    7. sudo update-initramfs -uで更新反映
    8. sudo vi /etc/default/grubのCMDLINEを以下に変更
      GRUB_CMDLINE_LINUX_DEFAULT="text"
    9. 変更更新
      update-grub
      update-grub2
      sudo init 6 # 再起動
    10. 起動したら以下打って確認
      lsmod | grep nouveau #何も表示されないことを確認
    11. debのインストール
      コマンドなんだっけ
    12. grubをGUIに戻す
      GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
    13. 変更更新して再起動
      sudo update-initramfs -u
      sudo init 6 # 再起動
    14. GUIモードになったら,サンプルチェック
      • 煙のサンプルが動くことを確認.
      • /usr/local/cuda-7.5/samples/0_Simple/template
      • /usr/local/cuda-7.5/samples/5_Graphics/particle

Arrayfire

  • バイナリインストーラを使うこと
    • gitは設定とコンパイルが面倒
    • OpenCLは使わないことにした
sudo aptitude install libopenblas-dev
sudo aptitude install build-essential cmake cmake-curses-gui xorg-dev libglu1-mesa-dev
git clone https://github.com/arrayfire/arrayfire/wiki/GLFW-for-ArrayFire
wget https://github.com/glfw/glfw/archive/3.0.4.zip -O glfw-3.0.4.zip
unzip glfw-3.0.4.zip
cd glfw-3.0.4
mkdir build
cd build
cmake .. -DBUILD_SHARED_LIBS=ON
make -j8
sudo make install

http://www.arrayfire.com/docs/installing.htm#Ubuntu
sudo ./ArrayFire-v3.2.2_Linux_x86_64.sh --exclude-subdir --prefix=/usr/local
sudo apt-add-repository ppa:keithw/glfw3
sudo aptitude update
sudo aptitude install libglfw3-dev
cd ~
cp -r /usr/local/share/ArrayFire/examples .
cd examples
mkdir build
cd build
cmake ..
make

ArrayFire?

  • 素人が適当にCUDAで組むより早い!
  • n * n行列(ランダムに初期化,密行列)演算.100x100行列の二乗からGPUのほうが早い!

ベンチマーク

  • GTX 960
    1 * 1 time: 7.11001e-05, GFlops: 2.81294e-05
    2 * 2 time: 0.000118369, GFlops: 0.00013517
    4 * 4 time: 0.000118451, GFlops: 0.00108062
    8 * 8 time: 0.000118374, GFlops: 0.00865055
    16 * 16 time: 0.000118299, GFlops: 0.0692486
    32 * 32 time: 0.000118254, GFlops: 0.554198
    64 * 64 time: 0.000118398, GFlops: 4.42818
    128 * 128 time: 0.00011918, GFlops: 35.1931
    256 * 256 time: 0.000118702, GFlops: 282.678
    512 * 512 time: 0.000530851, GFlops: 505.67
    1024 * 1024 time: 0.003441, GFlops: 624.087
    2048 * 2048 time: 0.025118, GFlops: 683.966
    4096 * 4096 time: 0.207298, GFlops: 663.002
    8192 * 8192 time: 1.64625, GFlops: 667.889
    16384 * 16384 time: 13.2567, GFlops: 663.518
  • AMD Phenom(tm) II X6 1100T Processor(並列化してる???TODO)
    1 * 1 time: 3.87344e-07, GFlops: 0.00516337
    2 * 2 time: 4.20973e-07, GFlops: 0.0380072
    4 * 4 time: 4.42147e-07, GFlops: 0.289497
    8 * 8 time: 6.19577e-07, GFlops: 1.65274
    16 * 16 time: 1.31718e-06, GFlops: 6.21933
    32 * 32 time: 5.1171e-06, GFlops: 12.8072
    64 * 64 time: 3.1213e-05, GFlops: 16.7971
    128 * 128 time: 0.000147203, GFlops: 28.4934
    256 * 256 time: 0.000705, GFlops: 47.5949
    512 * 512 time: 0.005114, GFlops: 52.4903
    1024 * 1024 time: 0.030352, GFlops: 70.7526
    2048 * 2048 time: 0.281418, GFlops: 61.0475
    4096 * 4096 time: 2.49413, GFlops: 55.1049
    8192 * 8192 time: 23.0691, GFlops: 47.6618 
    16384 * 16384 time: 185.721, GFlops: 47.3618

API

  • 基本
    • 名前空間はaf
    • Eigen::MatrixXf?に相当するのはarray
シンボル説明備考
randu(m, n)0-1に初期化されたm x n行列を作成
timeit(func)void (*func)(void)の実行時間を返すfuncが早く終わる場合は1秒間何回も実行した平均
timer::start()timer t = timer::start(); proc(); double proc_time = timer::stop(t);で時間計測出来るなぜかproc_time = 0だったことがある.怪しい.
*オペレータ要素積行列積でないので注意!!
matmul(a, b)行列積

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS