2013-03-07 3 views
-2

Я изучаю CUDA. Сегодня я пробую код в книге: CUDA Application Design And Development, что меня удивляет. Почему CUDA Thrust так медленно? Вот код и вывод.Уменьшение тяги CUDA происходит так медленно?

#include <iostream> 
using namespace std; 

#include<thrust/reduce.h> 
#include<thrust/sequence.h> 
#include<thrust/host_vector.h> 
#include<thrust/device_vector.h> 
#include <device_launch_parameters.h> 

#include "GpuTimer.h" 

__global__ void fillKernel(int *a, int n) 
{ 
    int tid = blockDim.x * blockIdx.x + threadIdx.x; 
    if(tid <n) a[tid] = tid; 
} 

void fill(int *d_a, int n) 
{ 
    int nThreadsPerBlock = 512; 
    int nBlock = n/nThreadsPerBlock + ((n/nThreadsPerBlock)?1:0); 
    fillKernel<<<nBlock, nThreadsPerBlock>>>(d_a, n); 
} 

int main() 
{ 
    const int N = 500000; 
    GpuTimer timer1, timer2; 

    thrust::device_vector<int> a(N); 

    fill(thrust::raw_pointer_cast(&a[0]), N); 

    timer1.Start(); 
    int sumA = thrust::reduce(a.begin(), a.end(), 0); 
    timer1.Stop(); 

    cout << "Thrust reduce costs " << timer1.Elapsed() << "ms." << endl; 

    int sumCheck = 0; 
    timer2.Start(); 
    for(int i = 0; i < N; i++) 
     sumCheck += i; 
    timer2.Stop(); 

    cout << "Traditional reduce costs " << timer2.Elapsed() << "ms." << endl; 
    if (sumA == sumCheck) 
     cout << "Correct!" << endl; 
    return 0; 
} 

enter image description here

+4

Возможно, потому, что ваш размер входных данных довольно мал, или ваш графический процессор работает довольно медленно, или ваш хост-процессор довольно быстрый, или ваша платформа CUDA, как много латентности? Как мы можем ответить, почему ваш конкретный эксперимент не соответствует произвольному ожидаемому результату, когда мы не знаем, как эксперимент был выполнен? – talonmies

ответ

5

Вы не корректное сравнение. Ваш код GPU делает это:

int sumA = thrust::reduce(a.begin(), a.end(), 0); 

Ваш код процессора делает это:

for(int i = 0; i < N; i++) 
    sumCheck += i; 

Есть так много проблем с этой методологией я не уверен, с чего начать. Прежде всего, операция GPU является действительным сокращением, которое даст правильный результат для любой последовательности чисел в векторе a. Так получилось, что у вас есть последовательность от 1 до N в a, но это не обязательно должно быть так, и это все равно даст правильный результат. Код ЦП только дает правильный ответ для определенную последовательность от 1 до N. Во-вторых, интеллектуальный компилятор может оптимизировать вывод из вашего кода ЦП, существенно уменьшая этот весь цикл до постоянной инструкции присваивания. (Суммирование от 1 до N является просто (N + 1) (N/2), не так ли?) Я не знаю, какие оптимизации могут происходить под капотом на стороне процессора.

Более достоверным сравнением было бы сделать фактическое произвольное сокращение в обоих случаях. Примером может служить эталонный упор: уменьшить работу на векторе устройства и работать с вектором-хозяином. Или напишите свой собственный серийный код восстановления ЦП, который фактически работает с вектором, а не суммирует целые числа от 1 до N.

И как указано в комментариях, если вы серьезно относитесь к желанию получить помощь, документируйте такие вещи, как HW и SW, на которой вы работаете, а также предоставить весь код. Я понятия не имею, что делает GPUtimer. Я голосую, чтобы закрыть это как «слишком локализованное», потому что я не думаю, что кто-то найдет это полезное сравнение, используя такую ​​методологию.

+0

спасибо. Я действительно новичок в CUDA, и когда-то я слишком много ожидаю. Я думаю, что закрыть этот вопрос является хорошим предлогом. – hakunami

 Смежные вопросы

  • Нет связанных вопросов^_^