numba cudaを何度かリコールした後、動作が遅くなるのはなぜですか?

ピーター・デン

numba内でcudaを使用する方法を実験しています。しかし、私は自分の予想とは異なる何かに遭遇しました。これが私のコードです

from numba import cuda
@cuda.jit
def matmul(A, B, C):
"""Perform square matrix multiplication of C = A * B
"""
d=cuda.local.array((3,3),dtype=numba.float64)
i, j = cuda.grid(2)
if i < C.shape[0] and j < C.shape[1]:
    tmp = 0.
    for k in range(A.shape[1]):
        tmp += A[i, k] * B[k, j]
    C[i, j] = tmp

これは、numba.cudaを使用してテストするために私が自己定義した行列関数です。テストを実行する前に、次のコードで配列もロードしました。

import numpy as np
a=np.random.rand(2000,2000)
b=np.random.rand(2000,2000)
c=np.empty((2000,2000))
a1=cuda.to_device(a)
b1=cuda.to_device(b)
c1=cuda.to_device(c)

次に、実験に次のコードを使用しました。

from time import time
count =0
start=time()
for i in range(2000):
  matmul[(256,256),(16,16)](a1,b1,c1)
  count +=1
  print(count)

forループは、最初の1028回の実行で非常に高速に実行されました。ただし、1028日以降は実行速度が非常に遅くなりました。正確な原因と修正方法を教えてください。ちなみに私はwin10で走っています。

これがnumba.cudaから呼び出された私のcuda情報です

from numba import cuda
gpu = cuda.get_current_device()
print("name = %s" % gpu.name)
print("maxThreadsPerBlock = %s" % str(gpu.MAX_THREADS_PER_BLOCK))
print("maxBlockDimX = %s" % str(gpu.MAX_BLOCK_DIM_X))
print("maxBlockDimY = %s" % str(gpu.MAX_BLOCK_DIM_Y))
print("maxBlockDimZ = %s" % str(gpu.MAX_BLOCK_DIM_Z))
print("maxGridDimX = %s" % str(gpu.MAX_GRID_DIM_X))
print("maxGridDimY = %s" % str(gpu.MAX_GRID_DIM_Y))
print("maxGridDimZ = %s" % str(gpu.MAX_GRID_DIM_Z))
print("maxSharedMemoryPerBlock = %s" % 
str(gpu.MAX_SHARED_MEMORY_PER_BLOCK))
print("asyncEngineCount = %s" % str(gpu.ASYNC_ENGINE_COUNT))
print("canMapHostMemory = %s" % str(gpu.CAN_MAP_HOST_MEMORY))
print("multiProcessorCount = %s" % str(gpu.MULTIPROCESSOR_COUNT))
print("warpSize = %s" % str(gpu.WARP_SIZE))
print("unifiedAddressing = %s" % str(gpu.UNIFIED_ADDRESSING))
print("pciBusID = %s" % str(gpu.PCI_BUS_ID))
print("pciDeviceID = %s" % str(gpu.PCI_DEVICE_ID))

出力は次のとおりです。

名前= b'GeForce GTX 1050 Ti '

maxThreadsPerBlock = 1024

maxBlockDimX = 1024

maxBlockDimY = 1024

maxBlockDimZ = 64

maxGridDimX = 2147483647

maxGridDimY = 65535

maxGridDimZ = 65535

maxSharedMemoryPerBlock = 49152

asyncEngineCount = 2

canMapHostMemory = 1

multiProcessorCount = 6

ワープサイズ= 32

UnifiedAddressing = 1

pciBusID = 3

pciDeviceID = 0

ロバート・クロベラ

これは、GPUカーネルの起動に関連付けられた非同期起動キューが原因で発生します。

numbaにGPUカーネルを送信するように指示する場合:

matmul[(256,256),(16,16)](a1,b1,c1)

このリクエストはキューに入り、GPUカーネルがまだ完了していないか、まだ開始されていなくても、そのカーネル呼び出しを発行したCPUスレッド(つまりPython)は続行できます。

CUDAランタイムはこれらのリクエストをキューに入れ、GPUがさらなる作業の準備ができるとそれらを発行します。

forループの非常に高速なインクリメント中に最初に目撃しているのは、キューが作業要求でいっぱいになっていることです。これは、GPUが作業を実行するために必要な実際の時間を表すものではありません。

最終的にキューがいっぱいになり、CUDAランタイムはカーネルの起動時にキュースロットが開くまでCPUスレッド(つまりPython)を停止します。その時点で、forループはもう1回繰り返されます。この時点(おそらく約1028回の反復)で「スローダウン」が見られ始めます。その後、forループは、GPUカーネルが実行され、処理キューから削除される速度ほぼ同じ速度で進行します。

ここで修正するものはありません。これは予想される動作です。

GPUカーネルが実際に実行される速度でのみ、forループを続行する場合は、forループに同期関数を挿入する必要があります。

たとえば、numbaはnumba.cuda.synchronize()を提供します。したがって、forループを次のように変更すると次のようになります。

for i in range(2000):
  matmul[(256,256),(16,16)](a1,b1,c1)
  cuda.synchronize()
  count +=1
  print(count)

forループは、「キュー充填」速度ではなく、GPU作業完了の実際の速度で進行することがわかります。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

numba.cudaとCuPyを同時に使用すると、GPUからデータを転送するのが非常に遅いのはなぜですか?

分類Dev

Numbaのnamedtuple署名

分類Dev

私のコードでnumbaが純粋なPythonよりも遅いのはなぜですか?

分類Dev

Numba pyccのコンパイルが中止されるのはなぜですか?

分類Dev

numba (cuda python) で 1D 配列の正しい合計を取得できないのはなぜですか?

分類Dev

Numbaがこの関数のコンパイルに失敗するのはなぜですか?

分類Dev

このnumba.cudaルックアップテーブルの実装が失敗するのはなぜですか?

分類Dev

numba @jitはその純粋なPythonより遅いですか?

分類Dev

なぜNumbaはこの反復を改善しないのですか...?

分類Dev

numba熱心なコンパイル?パターンは何ですか?

分類Dev

CUDA関数がNumbaを使用したPythonでForループを実行しない

分類Dev

この単純な追加関数のこのCython実装がNumbaよりも遅いのはなぜですか?

分類Dev

NumPy配列を反復するときにCythonがNumbaよりもはるかに遅いのはなぜですか?

分類Dev

CUDA-Python:Python(Numba 0.25)でCUDAカーネルを起動する方法は?

分類Dev

CUDAのNumba.vectorize:配列を返すための正しい署名は何ですか?

分類Dev

Python Numba Cuda Copy_To_Host Slow

分類Dev

numbaがナップザック機能の速度を改善しないのはなぜですか?

分類Dev

日時のあるNumba

分類Dev

numbaのintの配列

分類Dev

Numbaによる並列化

分類Dev

numbaの関数タイプ

分類Dev

ここでnumbaがnumpyより速いのはなぜですか?

分類Dev

numbaがこの入れ子関数で機能しないのはなぜですか?

分類Dev

Numba LLVM:10進表現での奇妙な動作エラー

分類Dev

numbaでの面白い動作-argmax()を使用したguvectorized関数

分類Dev

numpy.bitwise_およびブール配列ではnumbaが遅くなります

分類Dev

numbaとnumpyがインプレース操作で異なるパフォーマンスをするのはなぜですか?

分類Dev

numbaとcythonよりもnumpyが速い、numbaコードを改善する方法

分類Dev

Numbaで構造化された配列/データフレームのような構造を取得するための最良の方法は何ですか?

Related 関連記事

  1. 1

    numba.cudaとCuPyを同時に使用すると、GPUからデータを転送するのが非常に遅いのはなぜですか?

  2. 2

    Numbaのnamedtuple署名

  3. 3

    私のコードでnumbaが純粋なPythonよりも遅いのはなぜですか?

  4. 4

    Numba pyccのコンパイルが中止されるのはなぜですか?

  5. 5

    numba (cuda python) で 1D 配列の正しい合計を取得できないのはなぜですか?

  6. 6

    Numbaがこの関数のコンパイルに失敗するのはなぜですか?

  7. 7

    このnumba.cudaルックアップテーブルの実装が失敗するのはなぜですか?

  8. 8

    numba @jitはその純粋なPythonより遅いですか?

  9. 9

    なぜNumbaはこの反復を改善しないのですか...?

  10. 10

    numba熱心なコンパイル?パターンは何ですか?

  11. 11

    CUDA関数がNumbaを使用したPythonでForループを実行しない

  12. 12

    この単純な追加関数のこのCython実装がNumbaよりも遅いのはなぜですか?

  13. 13

    NumPy配列を反復するときにCythonがNumbaよりもはるかに遅いのはなぜですか?

  14. 14

    CUDA-Python:Python(Numba 0.25)でCUDAカーネルを起動する方法は?

  15. 15

    CUDAのNumba.vectorize:配列を返すための正しい署名は何ですか?

  16. 16

    Python Numba Cuda Copy_To_Host Slow

  17. 17

    numbaがナップザック機能の速度を改善しないのはなぜですか?

  18. 18

    日時のあるNumba

  19. 19

    numbaのintの配列

  20. 20

    Numbaによる並列化

  21. 21

    numbaの関数タイプ

  22. 22

    ここでnumbaがnumpyより速いのはなぜですか?

  23. 23

    numbaがこの入れ子関数で機能しないのはなぜですか?

  24. 24

    Numba LLVM:10進表現での奇妙な動作エラー

  25. 25

    numbaでの面白い動作-argmax()を使用したguvectorized関数

  26. 26

    numpy.bitwise_およびブール配列ではnumbaが遅くなります

  27. 27

    numbaとnumpyがインプレース操作で異なるパフォーマンスをするのはなぜですか?

  28. 28

    numbaとcythonよりもnumpyが速い、numbaコードを改善する方法

  29. 29

    Numbaで構造化された配列/データフレームのような構造を取得するための最良の方法は何ですか?

ホットタグ

アーカイブ