2011-08-13 8 views
2

그래서 GPGPU 에뮬레이터를 C & pthreads로 만들려고했으나 왜 이상한 문제가 발생했는지는 알지 못합니다. 코드는 다음과 같습니다 :C pthread 분할 오류

#include <stdlib.h> 
#include <stdio.h> 
#include <pthread.h> 
#include <assert.h> 

// simplifies malloc 
#define MALLOC(a) (a *)malloc(sizeof(a)) 

// Index of x/y coordinate 
#define x (0) 
#define y (1) 

// Defines size of a block 
#define BLOCK_DIM_X (3) 
#define BLOCK_DIM_Y (2) 

// Defines size of the grid, i.e., how many blocks 
#define GRID_DIM_X (5) 
#define GRID_DIM_Y (7) 

// Defines the number of threads in the grid 
#define GRID_SIZE (BLOCK_DIM_X * BLOCK_DIM_Y * GRID_DIM_X * GRID_DIM_Y) 

// execution environment for the kernel 
typedef struct exec_env { 
    int threadIdx[2]; // thread location 
    int blockIdx[2]; 
    int blockDim[2]; 
    int gridDim[2]; 

    float *A,*B;  // parameters for the thread 
    float *C; 
} exec_env; 

// kernel 
void *kernel(void *arg) 
{ 
    exec_env *env = (exec_env *) arg; 

    // compute number of threads in a block 
    int sz = env->blockDim[x] * env->blockDim[y]; 

    // compute the index of the first thread in the block 
    int k = sz * (env->blockIdx[y]*env->gridDim[x] + env->blockIdx[x]); 

    // compute the index of a thread inside a block 
    k = k + env->threadIdx[y]*env->blockDim[x] + env->threadIdx[x]; 

    // check whether it is in range 
    assert(k >= 0 && k < GRID_SIZE && "Wrong index computation"); 

    // print coordinates in block and grid and computed index 
    /*printf("tx:%d ty:%d bx:%d by:%d idx:%d\n",env->threadIdx[x], 
               env->threadIdx[y], 
               env->blockIdx[x], 
               env->blockIdx[y], k); 
    */ 

    // retrieve two operands 
    float *A = &env->A[k]; 
    float *B = &env->B[k]; 
    printf("%f %f \n",*A, *B); 
    // retrieve pointer to result 
    float *C = &env->C[k]; 

    // do actual computation here !!! 

    // For assignment replace the following line with 
    // the code to do matrix addition and multiplication. 
    *C = *A + *B; 

    // free execution environment (not needed anymore) 
    free(env); 

    return NULL; 
} 


// main function 
int main(int argc, char **argv) 
{ 
    float A[GRID_SIZE] = {-1}; 
    float B[GRID_SIZE] = {-1}; 
    float C[GRID_SIZE] = {-1}; 

    pthread_t threads[GRID_SIZE]; 

    int i=0, bx, by, tx, ty; 
    //Error location 
    /*for (i = 0; i < GRID_SIZE;i++){ 
     A[i] = i; 
     B[i] = i+1; 
     printf("%f %f\n ", A[i], B[i]); 
    }*/ 

    // Step 1: create execution environment for threads and create thread 
    for (bx=0;bx<GRID_DIM_X;bx++) { 
     for (by=0;by<GRID_DIM_Y;by++) { 
     for (tx=0;tx<BLOCK_DIM_X;tx++) { 
      for (ty=0;ty<BLOCK_DIM_Y;ty++) { 

       exec_env *e = MALLOC(exec_env); 
       assert(e != NULL && "memory exhausted"); 

       e->threadIdx[x]=tx; 
       e->threadIdx[y]=ty; 

       e->blockIdx[x]=bx; 
       e->blockIdx[y]=by; 

       e->blockDim[x]=BLOCK_DIM_X; 
       e->blockDim[y]=BLOCK_DIM_Y; 

       e->gridDim[x]=GRID_DIM_X; 
       e->gridDim[y]=GRID_DIM_Y; 

       // set parameters 
       e->A = A; 
       e->B = B; 
       e->C = C; 

       // create thread 
       pthread_create(&threads[i++],NULL,kernel,(void *)e); 
      } 
     } 
     } 
    } 

    // Step 2: wait for completion of all threads 
    for (i=0;i<GRID_SIZE;i++) { 
     pthread_join(threads[i], NULL); 
    } 

    // Step 3: print result  
    for (i=0;i<GRID_SIZE;i++) { 
     printf("%f ",C[i]); 
    } 
    printf("\n"); 

    return 0; 
} 

확인이 코드는 여기에 잘 실행하지만, 최대한 빨리 루프 ("오류 위치"의 주석으로 지정하는 A [I] = i와 B [I] = I + 1, 나는 유닉스에서 segmentation fault에 의해 cygwin에서 C 내의 임의의 0s에 의해 짤깍 소리가났다. 나는 C에서의 나의 fundamentals이 꽤 가난하다는 것을 인정해야한다. 그래서 나는 뭔가를 놓쳤을 가능성이 높다. 누군가가 아이디어를 줄 수 있다면 잘못 무슨 일이 일어나고 있는지에 크게 감사 것입니다. 감사합니다. 당신이 i은 여전히 ​​0이기 때문에 4 중첩 루프를 시작할 때 언급 할 때

답변

5

그것은 작동합니다.

당신의 시간을 이 집결지 :

for (i = 0; i < GRID_SIZE;i++){ 
    A[i] = i; 
    B[i] = i+1; 
    printf("%f %f\n ", A[i], B[i]); 
} 

/* What value is `i` now ? */ 

그리고

pthread_create(&threads[i++],NULL,kernel,(void *)e); 
         ^

그래서 pthread_create 참으로 흥미로운 인덱스를 액세스하려고 할 것이다.

+0

나는 단지 facepalmed입니다. 덕분에 많은 cnicutar! –