GPUでの計算がCPUよりも遅くなる原因

6,909 views
Skip to first unread message

sohei arisaka

unread,
Aug 25, 2016, 1:22:35 AM8/25/16
to Chainer Japanese User Group
お世話になっております。
時系列データをauto-encoderにかけるプログラムを作成していますが、
GPUでの実行の方がCPUでの実行よりも遅くなってしまいます。
gpu : 165iter/sec
cpu : 300iter/sec

どこがネックになっているのか、どのように書き直せばよいのか分からず困っております。
コードを添付いたしますので、解決法をご教示いただけないでしょうか。
実行環境はAWSを使用しており、サンプルのmnistのコードでは
GPUで正常に(CPUよりも速く)実行できることを確認しています。
インスタンス: g2.xlarge
AMI: Bitfusion Boost Ubuntu 14 Caffe
chainer: v1.14.0

何卒よろしくお願いいたします。
auto-encoder2.py
nvprof.txt

Yuya Unno

unread,
Aug 25, 2016, 10:29:34 AM8/25/16
to sohei arisaka, Chainer Japanese User Group
GPUで早くなる条件は、大雑把に言えば1.ちゃんとGPUをつかいきる、2. 無駄な待ち時間が発生しない、という点が大きいです。
1はミニバッチサイズが影響を受けます。バッチサイズを確認してください。十分大きくする必要があります
2は同期の頻度の問題になります。同期が発生するのはto_cpuなど、cupy.ndarrayの値を取得するところで主に発生します。無駄な転送が起こっていないか確認してください。

パフォーマンスの確認は、nvprofよりnvvpの方が確実です。そちらの利用も検討してください

2016年8月25日 14:22 sohei arisaka <cramp...@gmail.com>:

--
このメールは Google グループのグループ「Chainer Japanese User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには chainer-jp+unsubscribe@googlegroups.com にメールを送信してください。
このグループに投稿するには chain...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/chainer-jp/c5d73598-a10a-481b-aa5a-0bc10eca603c%40googlegroups.com にアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

Message has been deleted

sohei arisaka

unread,
Aug 25, 2016, 9:12:40 PM8/25/16
to Chainer Japanese User Group, cramp...@gmail.com
お返事ありがとうございます。

・1について
バッチサイズを100から1000に変えてみたところ、以下の結果になりました。
gpu : 90iter/sec
cpu : 110iter/sec
バッチサイズ1000はかなり大きいという認識なのですが、
さらにバッチサイズを大きくする必要があるのでしょうか。

・2について
学習にはTrainerを利用しております。コード内でGPUに関する部分は
chainer.cuda.get_device(0).use()  # Make a specified GPU current
model.to_gpu()  # Copy the model to the GPU
updater = training.StandardUpdater(train_iter, optimizer, device=0)
trainer.extend(extensions.Evaluator(test_iter, model, device=0))
だけだと認識しているのですが、過不足がありますでしょうか。

素人質問で恐縮ですが、ご回答いただけないでしょうか。
また、パフォーマンス確認についてもご助言いただきありがとうございます。
nvvpでも確認してみます。

よろしくお願いいたします。


2016年8月25日木曜日 23時29分34秒 UTC+9 Yuya Unno:
GPUで早くなる条件は、大雑把に言えば1.ちゃんとGPUをつかいきる、2. 無駄な待ち時間が発生しない、という点が大きいです。
1はミニバッチサイズが影響を受けます。バッチサイズを確認してください。十分大きくする必要があります
2は同期の頻度の問題になります。同期が発生するのはto_cpuなど、cupy.ndarrayの値を取得するところで主に発生します。無駄な転送が起こっていないか確認してください。

パフォーマンスの確認は、nvprofよりnvvpの方が確実です。そちらの利用も検討してください
2016年8月25日 14:22 sohei arisaka <cramp...@gmail.com>:
お世話になっております。
時系列データをauto-encoderにかけるプログラムを作成していますが、
GPUでの実行の方がCPUでの実行よりも遅くなってしまいます。
gpu : 165iter/sec
cpu : 300iter/sec

どこがネックになっているのか、どのように書き直せばよいのか分からず困っております。
コードを添付いたしますので、解決法をご教示いただけないでしょうか。
実行環境はAWSを使用しており、サンプルのmnistのコードでは
GPUで正常に(CPUよりも速く)実行できることを確認しています。
インスタンス: g2.xlarge
AMI: Bitfusion Boost Ubuntu 14 Caffe
chainer: v1.14.0

何卒よろしくお願いいたします。

--
このメールは Google グループのグループ「Chainer Japanese User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには chainer-jp+...@googlegroups.com にメールを送信してください。

kitanokumo

unread,
Aug 31, 2016, 1:26:44 AM8/31/16
to Chainer Japanese User Group, cramp...@gmail.com
バッチサイズを上げてGPUとCPUの差が縮まっているということは、
やはりGPUの性能を使い切っていなかったということになります。
n_unitsが小さすぎるのではないでしょうか?いくらでやっていますか?

GPUの強みはCPUに比べて内部に大量の計算器を持っているために、計算を並列にこなせるところにあります。
例えば100回の計算が必要な状況があったとして、CPUは一度に2個の計算しかできないため50回処理が必要です。
GPUは一度に10個計算ができるので10回で済みます。
だから速いのです(各数字はイメージで実際はもっと大きいです)。

しかし、一度に4回しか計算が必要の無い小規模なネットワークだと、
CPUは2回、GPUは1回の処理で計算が終わることになりGPUの優位性がほとんど発揮されなくなります。

さらに一つの一つの計算器の計算速度はCPUよりも大幅に遅い欠点と、
GPUへのデータ転送に時間がかかることを踏まえるとCPUよりもGPUが遅くなってしまう事が多々あります。

nvidia-smi -l 1

でGPUの使用状況を1秒ごとに表示してくれるのでGPU使用率が100%に近い状況になっているかどうか調べてみてください(参考)。
n_unitsやミニバッチサイズが小さいと一度に必要な計算量が小さいため、
20%など低い数字になっていることが多いです。

sohei arisaka

unread,
Sep 4, 2016, 9:56:37 PM9/4/16
to Chainer Japanese User Group, cramp...@gmail.com
お返事ありがとうございます。

ご指摘の通り、ネットワークの規模が小さすぎたのが原因でした。
試しにn_unitsを大きくしてみたところ、GPUがCPUを上回ることが確認できました。
また、n_unitsが小さい場合はGPU使用率が小さく(15%程度)、
大きい場合には使用率も大きく(80%程度)なることが確認できました。

GPUとCPUの処理の特徴についても教えていただき、ありがとうございます。
大変勉強になりました。

2016年8月31日水曜日 14時26分44秒 UTC+9 kitanokumo:
Reply all
Reply to author
Forward
0 new messages