1

pyopenCL を使用して、Python でウェブカメラ ストリームの平均を計算しようとしています。テストとして、以下に示すように、いくつかのフレームにわたって代表的な行列の平均を計算しようとしています。

import pyopencl as cl
import numpy as np
import time
import os

os.environ['PYOPENCL_CTX']='0' 

ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
length = 480
width = 320
nFrames = 60

matrix = np.zeros(shape=(length,width,nFrames)).astype(np.float32)
for i in range(nFrames):
  matrix[:,:,i] = float(i)

matrix_GPU = np.zeros(shape=(length,width)).astype(np.float32)
matrix_CPU = np.zeros_like(matrix_GPU)
final_matrix = np.zeros_like(matrix2t)

matrix_GPU_vector = np.reshape(matrix_GPU,matrix_GPU.size)



mf = cl.mem_flags
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, matrix_GPU.nbytes)


prg = cl.Program(ctx, """
    __kernel void summatrices(const unsigned int size, 
                  __global float * a, 
                  __global float * b, 
                  __global float * sum) 
    {
    int i = get_global_id(0); 
    sum[i] = a[i] + b[i];
    }
    """).build()


t0 =  time.time() 
for i in range(nFrames):
    matrix_GPU = matrix[:,:,i].astype(np.float32)
    matrix_GPU_vector = np.reshape(matrix_GPU,matrix_GPU.size)
    a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=matrix_GPU_vector)
    b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=final_matrix)
    prg.summatrices(queue, matrix_GPU_vector.shape, None,np.int32(len(matrix_GPU_vector)), a_buf, b_buf, dest_buf)
    temp_matrix = np.empty_like(matrix_GPU_vector)
    cl.enqueue_copy(queue, temp_matrix , dest_buf)
    final_matrix = temp_matrix

final_matrix = final_matrix/nFrames
final_matrix = np.reshape(final_matrix,(length,width))
delta_t =  time.time()  - t0


print 'OpenCL GPU Multiplication: ' + str(delta_t)
matrix_CPU = np.sum(matrix[:,:,:], axis=2)/nFrames
delta_t =  time.time()  - (t0 + delta_t)

print 'OpenCL CPU Multiplication: ' + str(delta_t)
#print matrix
#print final_matrix
#print matrix_CPU

eq = (final_matrix==matrix_CPU).all()
print eq

ただし、私のコードは CPU よりも GPU の方が 30 倍遅いようです。これは、私の for ループの使用と、ワークグループの割り当て不足が原因である可能性が最も高いです。

Python の for ループを取り除き、ワークグループを適切に割り当てることはできますか?

4

2 に答える 2

0

あなたはそれがテストだと言ったので、一日の終わりには、いくつかの追加よりもはるかに多くの計算を行いたいと思います。コードを強化するために試すことができる 2 つのことを次に示します。

  1. a_buf と b_buf を毎回作成しないでください。バッファの作成にはコストがかかります。それらをループの外側で作成し、ループ内でcl.enqueue_write_buffer()関数または cl.enqueue_copy(). 最初の関数は廃止され、2 番目の関数に置き換えられたようです。だから、それは次のようなものでなければなりませんcl.enqueue_copy(queue, a_buf, matrix_GPU_vector)
  2. それほどコストはかからないと思いますが、matrix_GPU既にメモリ内で適切に整列されているマトリックスを再形成しないでください。

ところで、ウェブカメラからストリームを受信するアプリをシミュレートするテストを行う場合、RGB マトリックスを使用すべきではありませんか? つまり、int8 でより適切にシミュレートできる 24 ビット RGB 画像を受け取ることができるということですよね?

于 2013-07-19T10:04:57.150 に答える