2012-03-28 4 views
0

나는 CUDA 코드를 프로그래밍했다.CUDA가 예상대로 작동하지 않습니까?

unsigned long mask_buffer; 
int s; 
off_t p, 

for(p=0;p!=5000;p++) 
{ 
    for(s=start;s!=end;s++) 
    { 
     ref_off = *(((unsigned int*)(idx_base)) + p); 

     if((int)(first_indexes[s-start_sequence] % 8 - ref_off % 8) < 0) 
     { 
      int shamt2 = (ref_off % 8 - first_indexes[s-start_sequence] % 8); 
      mask_buffer = *((unsigned long *)(msk_base + (ref_off - first_indexes[s-start_sequence])/8)) >> shamt2; 

      if(((*(unsigned long *)(seqmaskc + 16 * (s-start_sequence)))^mask_buffer) << shamt2) 
       continue; 
     } 

     else if((int)(first_indexes[s-start_sequence] % 8 - ref_off % 8) == 0) 
     { 
      mask_buffer = *((unsigned long *)(msk_base + (ref_off)/8)); 

      if((*(unsigned long *)(seqmaskc + 16 * (s-start_sequence))^mask_buffer)) 
       continue; 
     } 

     else 
     { 
      int shamt2 = 8 - (first_indexes[s-start_sequence] % 8 - ref_off % 8); 
      mask_buffer = *((unsigned long *)(msk_base + (ref_off/8- first_indexes[s-start_sequence]/8) - 1)) >> shamt2; 

      if(((*(unsigned long *)(seqmaskc + 16 * (s-start_sequence)))^mask_buffer) << shamt2) 
       continue; 
     } 

     int shamt = (ref_off % 4 - first_indexes[s-start_sequence] % 4) * 2; 

     memcpy(reference_blk, ref_base + ref_off/4 - first_indexes[s-start_sequence]/4, sequence_bytes); 

     for (rp = last_rp ; rp != (unsigned long *) reference_blk ; rp--) 
     { 
      unsigned long tmp = ((*rp) & ((1 << shamt) - 1)) << (8 * sizeof(unsigned long) - shamt); 
      *rp = (*rp >> shamt) | shifted_in; 
      shifted_in = tmp; 
     } 

     *rp = (*rp >> shamt) | shifted_in; 

     if (sequence_length & 0x3) 
      reference_blk[sequence_length >> 2] &= (1 << ((sequence_length & 0x3) << 1)) - 1; 

     for (i = sequence_length >> 2 ; i & (SEQUENCE_ALIGN - 1) ; i++) 
      reference_blk[i] = 0; 

     //-- instead of memcmp --// 
     int v = 0; 
     char *p1 = (char *)sequence; 
     char *p2 = (char *)reference_blk; 
     int tmp_asd = sequence_bytes; 

     while(tmp_asd!=0) 
     { 
      v = *(p1++) - *(p2++); 

      if(v!=0) 
       break; 

      tmp_asd--; 
     } 

     if(v == 0) 
     { 
      mat_count[s - (int)start_sequence]++;  /* Maintain count */ 
      mat_position[s - (int)start_sequence] = ref_off-first_indexes[s-start_sequence]; /* Record latest position */ 
     } 

    } 
} 

이 for 루프는 내 코드의 주요 기능입니다. 그러나 문제는 변수 "p"가 5 또는 6 이상으로 증가하지 않는다는 것입니다. 내 컴퓨터에 GT530이 있고 내 CUDA 드라이버 버전과 런타임 버전도 4.0입니다. 이 코드의 문제점은 무엇입니까 ???

+0

전체 코드 또는 적어도 코드의 일부와 함께 유형을 포함 할 수 있습니까? –

+0

더 많은 문맥이 없으면 우리가 대단히 도움을 줄 수 있다고 생각하지 않습니다. 더 많은 코드를 붙여 넣을 수 있습니까? –

+0

내 코드 소스 편집 – Jimmy

답변

1

실제로 이것이 새로운 코드 편집 이전에 게시 된 원래의 커널이라고 가정하면 memcpy과 같은 표준 C 라이브러리 함수를 CUDA 커널 안에 호출 할 수 없습니다. 코드). 커널에서는 __device__ 기능 만 호출 할 수 있습니다. 따라서 CUDA에서 memcpy을 다시 구현하지 않는 한, 커널 내부에서 그 함수를 호출하면 작동하지 않습니다 ...

또한 결과를 확인해야하는 CUDA 커널을 작성하려고한다면 커널의 메모리 비교 섹션에서 수행하는 것처럼 그룹의 다른 스레드가 작성한 것보다 코드에 동기화 지점을 추가하여 모든 스레드가 특정 지점에 도달했는지 확인해야합니다 해당 스레드의 결과를 확인하기 시작하십시오. 또 다른 블록이 주 메모리에 기록되었을 수있는 내용을 확인하려는 경우 이전 주 스레드 블록의 결과가 주 메모리에 기록되도록 보장하는 동기화 기본도 있습니다.

+0

답변 해 주셔서 감사합니다. 하지만 내 프로그램은 아직 최종 버전이 아닙니다. 그래서 순차적 인 버전과 같이 1 개의 블록과 1 개의 스레드로이 코드를 실행 해 보았습니다. 동기화 문제는 매우 중요한 문제이지만 더 중요한 문제는 내가 생각하는 정확성 문제입니다. 그리고 memcpy를 다른 방법으로 변환하려고합니다. – Jimmy

+1

현재 Windows 또는 Linux를 사용하고 계십니까? 올바르게 기억한다면 적어도 2.x와 같은 이전 버전의 CUDA에서는 CUDA 커널을 실행중인 카드가 Windows 디스플레이 드라이버 시간 초과로 인해 5 초 이상 Windows CUDA 커널을 실행할 수 없습니다 Windows 바탕 화면이 확장되어 있습니다 ... 그래서 당신이 단일 스레드에서 실행중인 경우 문자열의 크기에 따라이 제한을 실행할 수 있습니다. – Jason

+0

나는 리눅스 환경에서 일하고있다. 답변 주셔서 감사합니다 – Jimmy

관련 문제