2013-09-13 2 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

#define ARR_SIZE 10 
#define NUM_DEVICE 1 

typedef struct { 
    int *arr; 
    int *dev_arr; 
    int *dev_result; 
    int *result; 
    int num; 
} cuda_st; 

__global__ void kernel_fc(int *dev_arr, int *dev_result) 
{ 
    int idx = threadIdx.x; 
    printf("dev_arr[%d] = %d\n", idx, dev_arr[idx]); 
    atomicAdd(dev_result, dev_arr[idx]); 
} 

void *thread_func(void* struc) 
{ 
    cuda_st * data = (cuda_st*)struc; 
    printf("thread %d func start\n", data->num); 
    printf("arr %d = ", data->num); 
    for(int i=0; i<10; i++) { 
     printf("%d ", data->arr[i]); 
    } 
    printf("\n"); 
    cudaSetDevice(data->num); 
    cudaMemcpy(data->dev_arr, data->arr, sizeof(int)*ARR_SIZE, cudaMemcpyHostToDevice); 
    kernel_fc<<<1,ARR_SIZE>>>(data->dev_arr, data->dev_result); 
    cudaMemcpy(data->result, data->dev_result, sizeof(int), cudaMemcpyDeviceToHost); 
    printf("thread %d func exit\n", data->num); 
    return NULL; 
} 

int main(void) 
{ 
    // Make object 
    cuda_st cuda[NUM_DEVICE]; 

    // Make thread 
    pthread_t pthread[NUM_DEVICE]; 

    // Host array memory allocation 
    int *arr[NUM_DEVICE]; 
    for(int i=0; i<NUM_DEVICE; i++) { 
     arr[i] = (int*)malloc(sizeof(int)*ARR_SIZE); 
    } 

    // Fill this host array up with specified data 
    for(int i=0; i<NUM_DEVICE; i++) { 
     for(int j=0; j<ARR_SIZE; j++) { 
      arr[i][j] = i*ARR_SIZE+j; 
     } 
    } 

    // To confirm host array data 
    for(int i=0; i<NUM_DEVICE; i++) { 
     printf("arr[%d] = ", i); 
     for(int j=0; j<ARR_SIZE; j++) { 
      printf("%d ", arr[i][j]); 
     } 
     printf("\n"); 
    } 

    // Result memory allocation 
    int *result[NUM_DEVICE]; 
    for(int i=0; i<NUM_DEVICE; i++) { 
     result[i] = (int*)malloc(sizeof(int)); 
     memset(result[i], 0, sizeof(int)); 
    } 

    // Device array memory allocation 
    int *dev_arr[NUM_DEVICE]; 
    for(int i=0; i<NUM_DEVICE; i++) { 
     cudaMalloc(&dev_arr[i], sizeof(int)*ARR_SIZE); 
    } 

    // Device result memory allocation 
    int *dev_result[NUM_DEVICE]; 
    for(int i=0; i<NUM_DEVICE; i++) { 
     cudaMalloc(&dev_result[i], sizeof(int)); 
     cudaMemset(dev_result[i], 0, sizeof(int)); 
    } 

    // Connect these pointers with object 
    for(int i=0; i<NUM_DEVICE; i++) { 
     cuda[i].arr = arr[i]; 
     cuda[i].dev_arr = dev_arr[i]; 
     cuda[i].result = result[i]; 
     cuda[i].dev_result = dev_result[i]; 
     cuda[i].num = i; 
    } 

    // Create and excute pthread 
    for(int i=0; i<NUM_DEVICE; i++) { 
     pthread_create(&pthread[i], NULL, thread_func, (void*)&cuda[i]); 
    } 

    // Join pthread 
    for(int i=0; i<NUM_DEVICE; i++) { 
     pthread_join(pthread[i], NULL); 
    } 

    for(int i=0; i<NUM_DEVICE; i++) { 
     printf("result[%d] = %d\n", i, (*cuda[i].result)); 
    } 

    return 0; 
} 

Я делаю свою простую тестовую программу, как это, чтобы проверить pthread с помощью многоцелевого кода cuda.cuda программирование с pthread

Когда NUM_DEVICE установлен как 1, он работает хорошо, но при установке в качестве остановки 2 программы.

Я предполагаю, что многопоточный доступ к cudaSetDevice, но я не знаю, как с этим справиться.

Я пытался сделать мою программу с одним хост-потоком и несколькими устройствами (с функцией Async) раньше, но в моем случае (не над простым кодом) есть много хост-кода между функциями ядра, поэтому он не работает хорошо асинхронно.

Так что я тестирую, чтобы использовать многопоточность на хосте, прежде чем применять этот способ к моему реальному коду, но у меня такие проблемы.

Должен ли я использовать асинхронную функцию в функциях и ядрах cuda?

Дайте мне совет.

+0

Сколько графических процессоров и есть ?? –

+0

Всего 2 устройства и оба - GTX580. – Umbrella

+0

Если у вас есть только одно устройство, и вы хотите работать с pthread, как вы показали выше, удалите cudaSetDevice (data-> num); Он должен работать нормально .. –

ответ

2

Проблема в том, что вы выделяете память на одном устройстве. Вам нужно позвонить cudaSetDevice перед тем cudaMalloc вызовов:

// Device array memory allocation 
int *dev_arr[NUM_DEVICE]; 
for(int i=0; i<NUM_DEVICE; i++) { 
    cudaSetDevice(i); 
    cudaMalloc(&dev_arr[i], sizeof(int)*ARR_SIZE); 
} 

// Device result memory allocation 
int *dev_result[NUM_DEVICE]; 
for(int i=0; i<NUM_DEVICE; i++) { 
    cudaSetDevice(i); 
    cudaMalloc(&dev_result[i], sizeof(int)); 
    cudaMemset(dev_result[i], 0, sizeof(int)); 
} 
+0

Ох. Я скучаю по нему. Спасибо! – Umbrella

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