2012-09-04 7 views
1

잘못된 결과를 제공합니다 :내가 다음과 같은 출력을 생성의 PyCuda 예에서 <a href="http://wiki.tiker.net/PyCuda/Examples/SimpleSpeedTest" rel="nofollow">SimpleSpeedTest.py</a>를 실행

Using nbr_values == 8192 
Calculating 100000 iterations 
SourceModule time and first three results: 
0.058294s, [ 0.005477 0.005477 0.005477] 
Elementwise time and first three results: 
0.102527s, [ 0.005477 0.005477 0.005477] 
Elementwise Python looping time and first three results: 
2.398071s, [ 0.005477 0.005477 0.005477] 
GPUArray time and first three results: 
8.207257s, [ 0.005477 0.005477 0.005477] 
CPU time measured using : 
0.000002s, [ 0.005477 0.005477 0.005477] 

처음 네 시간 측정이 합리적, 마지막 (0.000002s) 그러나 off off입니다. CPU 결과는 가장 느린 것이지만 가장 빠른 GPU 방법보다 몇 배 빠릅니다. 그래서 분명히 측정 된 시간은 잘못되었을 것입니다. 첫 번째 네 가지 결과에 대해 동일한 타이밍 방법이 정상적으로 작동하는 것으로 보아 이상합니다.

그래서 나는 SimpleSpeedTest.py에서 일부 코드를 가져다가 작은 테스트 파일을 만든 [2], 생산되는 :

time measured using option 1: 
0.000002s 
time measured using option 2: 
5.989620s 

옵션 1 개 조치 pycuda.driver.Event.record()를 사용하여 기간을 (SimpleSpeedTest.py에서와 같이), 옵션 2time.clock()을 사용합니다. 다시 옵션 1은 꺼져 있고 옵션 2는 합리적인 결과를 제공합니다 (테스트 파일을 실행하는 데 걸리는 시간은 약 6 초입니다).

왜 이런 일이 발생했는지 알 수 있습니까?

옵션 1 사용이 SimpleSpeedTest.py에서 승인 되었기 때문에 문제를 일으키는 설정 일 수 있습니까? 나는 GTX 470, 디스플레이 드라이버 301.42, CUDA 4.2, 파이썬 2.7 (64), PyCuda 2012.1, X5650 제온를 실행하고

[2] 테스트 파일 :

import numpy 
import time 
import pycuda.driver as drv 
import pycuda.autoinit 

n_iter = 100000 
nbr_values = 8192 # = 64 * 128 (values as used in SimpleSpeedTest.py) 

start = drv.Event() # option 1 uses pycuda.driver.Event 
end = drv.Event() 

a = numpy.ones(nbr_values).astype(numpy.float32) # test data 

start.record() # start option 1 (inserting recording points into GPU stream) 
tic = time.clock() # start option 2 (using CPU time) 

for i in range(n_iter): 
    a = numpy.sin(a) # do some work 

end.record() # end option 1 
toc = time.clock() # end option 2 

end.synchronize() 

events_secs = start.time_till(end)*1e-3 
time_secs = toc - tic 

print "time measured using option 1:" 
print "%fs " % events_secs 
print "time measured using option 2:" 
print "%fs " % time_secs 
+0

GPU ('testfile2.py')에서 아무 것도 실행하지 않으면 numpy 배열을 만드는 것뿐입니다. 그래서'drv.Event'는 CPU가 아닌 GPU에서 소요 된 시간을 측정합니다. – dav1d

+0

@ dav1d 네, 이것이 문제가 될 수 있습니다. 그러나 이것이 사실이라면 왜 'SimpleSpeedTest.py'가 CPU에서 계산에 걸리는 시간을 측정하기 위해 옵션 1을 사용합니까? – Tobold

+0

잘 모르겠지만 버그 일 수 있습니다. 위키이기 때문에 파일을 편집하고 수정할 수 있습니다. – dav1d

답변

-1

내가 Andreas Klöckner 연락 그가 동기화 제안 시작 이벤트에서도 마찬가지입니다.

... 
start.record() 
start.synchronize() 
... 

그리고 이것은 문제를 해결하는 것 같습니다!

time measured using option 1: 
5.944461s 
time measured using option 2: 
5.944314s 

분명히 쿠다의 행동은 지난 2 년 동안 바뀌 었습니다. SimpleSpeedTest.py을 업데이트했습니다.

+0

start.synchronize()를 추가하면 start.record() 작업이 GPU로 푸시되고 GPU가 타임 스탬프를 메모리에 쓸 때까지 기다립니다. 이 코드는 추가 작업을 GPU에 푸시하는 것처럼 보이지 않습니다. 그런 다음 stop.record()를 사용하여 다른 CUDA 이벤트를 푸시하고 stop.synchronize()를 호출하여 GPU가 타임 스탬프를 작성할 때까지 기다립니다. 이것은 GPU 실행 시간이 아닌 CPU를 잡아내는 데있어서 매우 비범 한 방법입니다.고정밀 모노톤 타이머로 벽시계 시간을 캡처하려면 x86 타임 스탬프 카운터를 살펴 보는 것이 좋습니다. 이것은 gettimeofday() 및 QueryPerformanceCounter (> = Win7)에 의해 사용됩니다. –