Я не могу комментировать предыдущее решение, потому что я слишком нов, но продолжаю решение от Павана.Функция nnz (еще не реализована) для gpuArrays, по крайней мере, в версии Matlab, которую я использую (R2012a).
В общем, гораздо лучше векторизовать код Matlab.Однако в некоторых случаях зацикленный код может работать быстро в Matlab из-за компиляции JIT.
Проверьте результаты из
N = 1000;
randarray_cpu = rand(N,1);
randarray_gpu = gpuArray(randarray_cpu);
threshold = 0.5;
% CPU: looped
g=0;
tic
for i=1:N
if randarray_cpu(i)>threshold
g=g+1;
end
end
toc
% CPU: vectorized
tic
g = nnz(randarray_cpu>threshold);
toc
% GPU: looped
tic
g=0;
for i=1:N
if randarray_gpu(i)>threshold
g=g+1;
end
end
toc
% GPU: vectorized
tic
g_d = sum(randarray_gpu > threshold);
g = gather(g_d); % I'm assuming that you want this in the CPU at some point
toc
Что (на моем ядре i7 + GeForce 560Ti):
Elapsed time is 0.000014 seconds.
Elapsed time is 0.000580 seconds.
Elapsed time is 0.310218 seconds.
Elapsed time is 0.000558 seconds.
Итак, что мы видим из этого случая:
Циклы в Matlab не считаются хорошей практикой, но в вашем конкретном случае они работают быстро, потому что Matlab каким-то образом «прекомпилирует» его внутренне.Я изменил ваш порог с 10 до 0,5, так как rand никогда не даст вам значение, превышающее 1.
Зацикленная версия GPU работает ужасно, потому что на каждой итерации цикла запускается ядро (или данные считываются изGPU, однако TMW реализовал это ...), что медленно.Множество небольших переносов памяти при вычислении практически ничего не худшее, что можно сделать на графическом процессоре.
Исходя из последнего (лучшего) результата графического процессора, ответ будет таким: если данные уже находятся на графическом процессоре,не имеет смысла вычислять это на GPU.Поскольку арифметическая сложность вашей операции в основном отсутствует, накладные расходы на передачу памяти никоим образом не окупаются.Если это часть больших вычислений на GPU, это нормально.Если нет ... лучше придерживаться процессора;)