質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

8461閲覧

Cupyの計算速度がNumpyより遅い

roshikowami

総合スコア1

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/06/02 02:33

前提・実現したいこと

Pythonによる行列計算を高速で行いたいです。
行列数が多い計算をしたいので、
CPUで計算するNumpyではなく、GPUで計算するCupyを使用しています。
Cupyは以下のpipでインストールしました。

python

1pip install cupy-cuda110

発生している問題・エラーメッセージ

計算速度を比較するとNumpyよりCupyの方が遅い結果となりました。(Numpy:0.18秒 Cupy:1.12秒)
他のサイトでは、Cupyにすることで約100倍高速化できています。
積んでいるGPUのスペックによって差が生じることは理解していますが、
Cupyの方が遅いというのは他の要因によるものだと考えます。

該当のソースコード

python

1import numpy as np 2import cupy as cp 3import time 4 5n = 2000 6 7t1 = time.time() 8a = np.random.rand(n,n) 9b = np.random.rand(n,n) 10np.dot(a,b) 11t2 = time.time() 12a = cp.random.rand(n,n) 13b = cp.random.rand(n,n) 14cp.dot(a,b) 15t3 = time.time() 16print('np:',t2 - t1) 17print('cp:',t3 - t2)

試したこと

■NIDIA CUDA ツールキットのインストール
■NIDIA cuDNNのインストール
■環境変数の設定
【システム環境変数 Path】
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\libnvvp
【システム環境変数 CUDA_PATH】
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0
【システム環境変数 CUDA_PATH_V11_0】
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0
【システム環境変数 CUDNN_PATH】
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0
■タスクマネージャーで計算中にCUDAが動作していることを確認済み

補足情報(FW/ツールのバージョンなど)

■バージョン情報等
OS:Windows10
GPU:NVIDIA Quadro P520
Python:v3.9.0
Anaconda:v4.9.2
Cupy:v9.0.0
CUDA:v11.0
cuDNN:v8.0.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/06/02 02:45 編集

単純に計算量が少なすぎてということはないでしょうか http://segafreder.hatenablog.com/entry/2017/12/02/210452 > cupyは最初に使う関数はコンパイルされて計算時間が長くなりますが、以後はコンパイル結果がキャッシュされるので、キャッシュ入手後の状態で計測しています。
roshikowami

2021/06/02 02:57 編集

ご連絡ありがとうございます。 サイトを拝見しました。 たしかに行列積系の計算においてArray size(要素数)が10000以下だと、 Numpyと比較しCupyは同等以下の計算速度ですが、 Array sizeが1000000ではCupyによる高速化が図れています。 今回の計算はArray size=2000×2000=4000000の計算を行っておりますので、 計算量は十分だと考えます。
bsdfan

2021/06/02 03:59

乱数生成部分を含めずに計測したらどうなりますか?
jbpb0

2021/06/02 04:54 編集

当方で実行したら、初回はnumpyの勝ち、2回目以降はcupyの勝ちでした 「n = 10000」に変えたら、初回からcupyの勝ちでした (nを変える際は、念の為にPythonを落として立ち上げ直してます)
jbpb0

2021/06/02 05:20 編集

nを大きくするほどcupy有利になり、numpyと逆転するnはCPU, GPUの機種の組み合わせによって違う、ということではないですかね numpyのBLASの種類も効くかも (MKL使ってるかとか) 【追記】 初回は無視して2回目以降に限定すれば、numpyとcupyが互角になるのは、当方の環境ではn=20~30あたりでした
jbpb0

2021/06/02 06:30 編集

http://segafreder.hatenablog.com/entry/2017/12/02/210452 のプログラム https://gist.github.com/fukatani/4702aa05aed255cd25f42e77d0a22e37 を落として、そのまま実行してみました 結果がたくさん表示されますが、その内の一つだけ、上記Webページに記載の結果と比べてみます 条件:matmul、Array size=1000000 結果:Numpy, Cupy Web:43.664329052, 12.9769299316 当方:4.658911228179932, 3.5530239868164064 (2回目の結果) numpy, cupyどちらも、Webの記載よりも当方の方が高速に計算できてますが、特にnumpyの方がより改善できてます これは、OpenBLAS(Webページ)とMKL(当方)の違いも効いてるかもしれません その結果、numpyとcupyの比だけ見ると、Webページ結果ではcupyが3倍強速かったのに、当方の結果では2倍も違わない、となります だからといって、GPU性能が劣化してるのかというと、cupy同士の比較では4倍弱速くなっているのだから、そうではないですよね Web記載の数値と比較するのなら、numpyとcupyの比ではなく、GPU(cupy)結果同士を、同じプログラム・パラメータで比較する方がいいと思いますよ その比較のやり方で、GPUの同等機種や下位機種に負けてたら、それで初めて何かおかしいってなるわけです
roshikowami

2021/06/03 23:50

ご連絡ありがとうございます。 おっしゃる通り、 比較する際には同じ条件で比較することが重要だと理解しました。 まずはそこから始めてみます。
guest

回答1

0

ベストアンサー

全然性能出ないと思いますよ。そのコードだとFP64で演算が行われますが、

GPUの性能は、

FP64 (double) performance
35.83 GFLOPS (1:32)
NVIDIA Quadro P520 Mobile Specs | TechPowerUp GPU Database

のはずで、

次にCPUの性能ですが、

こちらの「FLOPs per cycle per core」と見比べると、

FLOPS - Wikipedia

理論値としてはskylake系のコアで16, icelake以降で32が期待できるので、動作周波数3GHz, numpy.dotはシングルコアで動作するとして、skylake系なら48GFLOPS、icelake以降なら96GFLOPS出ます。つまりそのGPUなら、(細かい条件次第ですが)負けても全然おかしくないことになります。

x86-64 CPUのFP64は意外と速いし、逆にGPUのFP64は遅いのです。ハイエンドのGPUならそれでもCPUより速く動くと期待して良いですが、ローエンドだとあまり期待はできません。
(FP32で使うという手はあります。1,147 GFLOPS出ることになっているので、こちらなら圧倒的に有利なはずです)


それはそれとして初期化の問題があるっぽいので、時間計測を始める前に

python

1a = cp.random.rand(n,n) 2b = cp.random.rand(n,n) 3cp.dot(a,b)

を一回実行してから計測を始めた方が公平な比較になりそうではあります(それでも遅いんじゃないかなぁと思ったりしますが)。


実装に依る気も若干しますが、素直に2000^3回の積算をこなすと仮定して8*10^9回ですから、35.83GFLOPSのP520で期待される行列積の処理時間は0.22秒くらい。3GHzで走っているskylake系CPUなら0.16秒。icelake以降ならその半分。

いずれも理論性能なので楽観的です。

GPUの方の1.12秒はかかりすぎだけど、ちゃんと性能を目一杯出させたとしても勝つかどうかは微妙なくらい、のはず。

投稿2021/06/02 12:38

編集2021/06/02 18:29
hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

roshikowami

2021/06/03 23:54

ご回答ありがとうございます。 丁寧な解説により、cpuが優秀だと理解しました。 また理論性能と実測値を比較することで、 計算速度が異常かどうか判定できそうだと感じました。 今後の参考とさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問