2013-02-10 3 views
0

답변을 찾을 수는 없지만 간단해야합니다. 저는 CUDA가 어떻게 작동 하는지를 알기 위해 세포 자동 장치의 상태를 계산해야하는 프로그램을 작성하고 있습니다. 아주 간단한 프로그램을 먼저 작성하려고했습니다. 그것은 행렬을 취하고 모든 스레드는 셀의 값과이 셀의 위와 아래에있는 셀을 증가시켜야합니다. 내가 그에게 다음과 같은 매트릭스 제공한다면, : 그것은 위의 행이 없기 때문에CUDA에서 여러 셀의 값을 변경하십시오.

[2 2 2 2 2 2 2] 
[3 3 3 3 3 3 3] 
[3 3 3 3 3 3 3] 
[3 3 3 3 3 3 3] 
[3 3 3 3 3 3 3] 
[3 3 3 3 3 3 3] 
[2 2 2 2 2 2 2] 

첫 번째 행, 2의 값이 :

[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 
[0 0 0 0 0 0 0] 

을 나는 다음과 같은 결과를 얻을 것으로 예상 첫 번째 행의 값을 한 번 더 늘릴 수 있습니다. ,

[2 2 2 2 2 2 2] 
[3 3 3 3 3 3 3] 
[3 3 3 3 3 3 3] 
[3 3 3 3 2 2 2] 
[2 2 2 2 2 2 2] 
[2 2 2 2 3 3 3] 
[2 2 2 2 2 2 2] 

을 그리고 2의 값은 4 거기 왜 나는 이해할 수 없다 : 그리고 유사한 방식으로 마지막 행은 2
의 값이 그러나 나는 다음과 같습니다 매트릭스를 받고 있어요

import numpy 
import pycuda.autoinit 
import pycuda.driver as cuda 

from pycuda.compiler import SourceModule 

w = 7 

mod = SourceModule(""" 
     __global__ void diffusion( int* result, int width, int height) { 

      int xIndex = blockDim.x * blockIdx.x + threadIdx.x; 
      int yIndex = blockDim.y * blockIdx.y + threadIdx.y; 

      int flatIndex = xIndex + width * yIndex; 
      int topIndex = xIndex + width * (yIndex - 1); 
      int bottomIndex = xIndex + width * (yIndex + 1); 

      int inc = 1; 

      result[flatIndex] += inc; 

      result[bottomIndex] += inc; 

      result[topIndex] += inc; 
     } 

     """) 

diff_func = mod.get_function("diffusion") 


def diffusion(res): 

    height, width = numpy.int32(len(res)), numpy.int32(len(res[0])) 

    diff_func(
     cuda.InOut(res), 
     width, 
     height, 
     block=(w,w,1) 
     ) 

def run(res, step): 

    diffusion(res) 
    print res 

res = numpy.array([[0 \ 
         for _ in xrange(0, w)]\ 
         for _ in xrange(0, w)], dtype='int32') 

run(res, 0) 

한 가지 더 흥미로운 점 : - 5, ATH 6 행하지 2. 여기
내 코드는 간다, 3있을이

result[bottomIndex] += inc; 
result[topIndex] += inc; 
,691,363 : 나는 다음과 같은 라인 중 하나를 언급하는 경우210

모든 것이 예상대로 작동하며 예기치 않은 값이 없습니다. 어떤 경우에는 CUDA가 한 스레드에서 인접한 세 개의 셀 값을 처리 할 수없는 것처럼 보입니다.

답변

2

당신은 메모리 경쟁으로 알고있는 것을 가지고 있습니다 : 여러 독립 스레드가 동시에 메모리의 동일한 값을 업데이트하려고 시도하고 있습니다. CUDA 메모리 모델은 두 스레드가 동일한 메모리 위치를 동시에 업데이트하려고 할 때 어떤 일이 발생하는지 정의하지 않습니다.

해결 방법은 원자 메모리 연산 (자세한 내용은 CUDA 프로그래밍 가이드 참조)이거나 인접한 셀을 업데이트하는 다른 접근 방법입니다 (예 : 그리드의 색을 지정하고 그리드를 통과 할 때마다 유색 셀처럼 업데이트).).

+0

예기치 않은 값을 가진 셀이 항상 같기 때문에 조사를하지는 않았습니다. 프로그램을 10 번 연속 호출 할 수 있으며, 4 번에서 6 번 행에는 항상 2 번이 있습니다. 예를 들어 2 ~ 3 또는 3 분의 1 정도입니다. 나는 자원에 대한 일종의 경쟁이 있다면 결과에 어떤 종류의 예측 불가능 성이 있어야한다고 생각했습니다. 어쨌든 답장을 보내 주셔서 감사 드리며, CUDA의 메모리 경주에 대해 자세히 살펴 보겠습니다. :) – aga