jupyter notebookでbenchmarkプログラミング

jupyter notebookで手軽にbenchmarkテストができるように、ベンチマークテスト用のプログラムを組む。というか、コードをコピペする。

先ずは必要なモジュールをインポートする。

from pycuda import autoinit, gpuarray
from pycuda import curandom
import numpy as np
import time
%pylab inline

次にテスト用のデータを用意して関数を書く

dprec = np.float32 # o np.float64
random = curandom.XORWOWRandomNumberGenerator()

def getTime(fun,n):
    timer = time.time()
    fun(n)
    return - timer + time.time()

def getRND_GPU_1D(n,r = False):
    real = random.gen_uniform(n,dprec)
    if r:
        plot(real.get())
    real.gpudata.free()
        
def getRND_GPU_2D(n,r = False):
    real = random.gen_uniform([n,n],dprec)
    if r:
        imshow(real.get())
        colorbar()
    real.gpudata.free()
        
def getRND_GPU_3D(n,r = False):
    real = random.gen_uniform([n,n,n],dprec)
    if r:
        imshow(real.get()[0,:,:])
        colorbar()
    real.gpudata.free()
    
def getRND_CPU_1D(n,r = False,gtt = False):
    real = np.random.rand(int(n)).astype(dprec)
    if r:
        plot(real)
    if gtt:
        return real

def getRND_CPU_2D(n,r = False,gtt = False):
    real = np.random.rand(int(n),int(n)).astype(dprec)
    if r:
        imshow(real)
        colorbar()
    if gtt:
        return real
        
def getRND_CPU_3D(n,r = False,gtt = False):
    real = np.random.rand(int(n),int(n),int(n)).astype(dprec)
    if r:
        imshow(real[0,:,:])
        colorbar()
    if gtt:
        return real

1D CPU/GPUベンチマーク($2^{1}$〜$2^{14}$)

2〜16384のCPU/GPU 1Dベンチマークテストの結果

import matplotlib.pylab as pylab
pylab.rcParams['figure.figsize'] = 14, 10
pylab.rcParams["font.size"] = "20"
cpuTime = []
gpuTime = []
nDim = []
for i in range(1,15):
    averT1 = 0
    averT2 = 0
    for j in range(10):
            averT1 += getTime(getRND_CPU_1D,2**i)
            averT2 += getTime(getRND_GPU_1D,2**i)
    cpuTime.append(averT1/10.)
    gpuTime.append(averT2/10.)
    nDim.append(2**i)
plot(nDim,cpuTime,'b-o', label ='CPU')
plot(nDim,gpuTime,'r*-', label ='GPU')
legend(loc=1,labelspacing=0.5,fancybox=True, handlelength=1.5, borderaxespad=0.25, borderpad=0.25)
xlabel('N')
ylabel('time')
print ('Time ratios cpu/gpu =', cpuTime[-1]/gpuTime[-1])
Time ratios cpu/gpu = 0.4764736750043728

データ量が小さいとCPUが速いが、データ量が増加するに連れGPUとの処理速度の差がどんどん縮まっていくのがよく分かる。

1D CPU/GPUベンチマーク($2^{1}$〜$2^{25}$)

2〜33554432のCPU/GPU 1Dベンチマークテストの結果

cpuTime = []
gpuTime = []
nDim = []
for i in range(1,26):
    averT1 = 0
    averT2 = 0
    for j in range(10):
            averT1 += getTime(getRND_CPU_1D,2**i)
            averT2 += getTime(getRND_GPU_1D,2**i)
    cpuTime.append(averT1/10.)
    gpuTime.append(averT2/10.)
    nDim.append(2**i)
plot(nDim,cpuTime,'b-o', label ='CPU')
plot(nDim,gpuTime,'r*-', label ='GPU')
legend(loc=1,labelspacing=0.5,fancybox=True, handlelength=1.5, borderaxespad=0.25, borderpad=0.25)
xlabel('N')
ylabel('time')
print ('Time ratios cpu/gpu =', cpuTime[-1]/gpuTime[-1])
Time ratios cpu/gpu = 18.334934654831237

データ量が巨大になっていくとGPUの独壇場になっていくのがよく分かる。

2D CPU/GPUベンチマーク($2^{15}$〜$2^{24}$)

32768〜16777216のCPU/GPU 2Dベンチマークテストの結果。

cpuTime = []
gpuTime = []
nDim = []
for i in range(15,25):
    averT1 = 0
    averT2 = 0
    for j in range(10):
            averT1 += getTime(getRND_CPU_1D,2**i)
            averT2 += getTime(getRND_GPU_1D,2**i)
    cpuTime.append(averT1/10.)
    gpuTime.append(averT2/10.)
    nDim.append(2**i)
plot(nDim,cpuTime,'b-o', label ='CPU')
plot(nDim,gpuTime,'r*-', label ='GPU')
legend(loc=1,labelspacing=0.5,fancybox=True, handlelength=1.5, borderaxespad=0.25, borderpad=0.25)
xlabel('N')
ylabel('time')
print ('Time ratios cpu/gpu =', cpuTime[-1]/gpuTime[-1])
Time ratios cpu/gpu = 18.62918863669942

ベンチマークテストは結果をグラフ化した方が分かりやすい。

参考サイトhttps://github.com/