2012-09-29 66 views
-2

,當我在CUDA計算,這是真的,但是當我使用更大的數量來計算,我必須設置TdrLevel爲
this link 。但是在設置了tdrlevel之後,我得到了一個錯誤的結果。 (-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080 -431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080-431602080)錯誤的結果時,在Win7 64位設置tdrlevel CUDA

我不知道在哪裏的問題。我的塊數爲512,每個塊的線程數爲1024。我希望找到我的意思。


that's my program code for fibunatchi program it work without tdrlevel but have above result by tdrlevel : 


#include <stdio.h> 
#include <cuda.h> 
#include <dos.h> 


__global__ void fibunat_array(float *a,int N) 
{  
    for (int x=0; x< N; x += 1) 
    { 
     a[x]=0; 
    } 
    a[0]=1;a[1]=1; 
    for (int i=0; i< N; i += 1) 
    { 
     a[i+2]=a[i]+a[i+1];  
    }  
} 

int main(void) 
{ 
    time_t start,end; 
    double dif; 
    time (&start); 

    float *a_h,*a_d; 
    const int N = 100; 

    size_t size = N * sizeof(float); 
    a_h = (float *)malloc(size);  

    cudaMalloc((void **)&a_d, size); 
    cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice); 

    int block_size = 9<<1; 
    int n_blocks = (N+ block_size-1) /block_size; 
    square_array <<< n_blocks , block_size >>> (a_d, N); 
    cudaMemcpy(a_h, a_d, sizeof(float) * N, cudaMemcpyDeviceToHost); 

    for (int i = 0; i<N/3+10 ; i++) 
     printf("%d ",(int)a_h[i]); 

    free(a_h); 
    cudaFree(a_d); 


    time (&end); 
    dif=difftime(end,start); 

    printf ("\n\n"); 
    printf ("total time for this calculate is : %d second\n\n",(int)dif); 

} 
+0

也許tdr禁用不起作用。如果您的顯示屏凍結,然後在運行cuda代碼時重新繪製自己,則tdr可能會觸發並且GPU正在重置。如果tdr似乎被正確禁用,那麼您的代碼中可能會有一個錯誤,它只會以較大的數據集顯示自身。 –

+0

感謝您的回答。我應該解釋一下,我在此路徑中添加零值TdrLevel:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ GraphicsDrivers。如果不製作這個文件,屏幕凍結和黑色片刻。但經過很多搜索後,我發現我應該在上面的路徑中添加TdrLevel。添加TdrLevel後,屏幕不凍結,黑色,但有錯誤的結果,我在第一評論解釋。我的代碼是sum數組中的簡單代碼。我希望你有這個問題的解決方案。謝謝 –

+0

那麼也許你的簡單的數組求和程序有一個錯誤,只顯示爲更大的值本身。它可能與tdr無關。你可能會發布你的代碼。下面是一個剛剛發佈在數組總和程序上的人的示例(http://stackoverflow.com/questions/12659988/cuda-memory-limit-vector-summation),該程序不適用於較大的數據集。 –

回答

1

這段代碼有幾個問題。例如,一個問題是你用一個名字爲fibunat_array的內核來定義內核,但是你調用一個名字爲square_array的內核。所以你發佈的代碼甚至不能正確編譯。另一個問題是,從串行代碼解決問題的角度來編寫內核,而不考慮並行運行線程。啓動內核時創建的每個線程都將運行完全相同的代碼。如果使用多個線程/塊,則這不起作用,並且不是利用機器的好方法。

您似乎想要計算fibonacci序列中的前100個數字。你可能想考慮這個的含義。這page可能會有所幫助。例如,該序列範圍中的一些最大數字將不適合64位整數。使用32位代碼,在序列中約有47個數字後,您的無符號整數大小將會過小。此外,創建一個平行的斐波那契發生器可能需要一個算法,它不像您想到的串行算法。即使你創建了一個平行斐波那契生成器,並且假設每個線程都計算了該系列的一個元素,但在100個元素內用完(64位)機器分辨率,這意味着你可以獲得最多的並行性在機器外面將少於100個線程(在這些假設下)。在串行算法上,加速方面可能不會給出非常令人滿意的結果,但這需要很多工作來完成。一般來說,當我們可以有數千個線程運行時,GPU會給出最好的結果。

說了這麼多,如果只是爲了證明點,你可以得到一些工作。由於您的原創作品中存在一些問題,因此只需提供能夠產生正確結果的代碼就簡單多了。這不是我會打電話合理利用GPU的,但你可以得到正確的結果與一些小的改動原來的代碼是這樣的:

#include <stdio.h> 
#include <cuda.h> 
// #include <dos.h> 


__global__ void fib(float *a,int N) 
{ 
    for (int x=0; x< N; x += 1) 
    { 
     a[x]=0; 
    } 
    a[0]=1;a[1]=1; 
    for (int i=0; i< (N-2); i += 1) 
    { 
     a[i+2]=a[i]+a[i+1]; 
    } 
} 

int main(void) 
{ 
// time_t start,end; 
// double dif; 
// time (&start); 

    float *a_h,*a_d; 
    const int N = 40; 

    size_t size = N * sizeof(float); 
    a_h = (float *)malloc(size); 

    cudaMalloc((void **)&a_d, size); 
    cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice); 

    // int block_size = 9<<1; 
    // int n_blocks = (N+ block_size-1) /block_size; 
    fib<<<1,1>>> (a_d, N); // just one thread does all the work 
    cudaMemcpy(a_h, a_d, sizeof(float) * N, cudaMemcpyDeviceToHost); 

    for (int i = 0; i<N ; i++) 
    printf("%d ",(int)a_h[i]); 

    printf("\n"); 
    free(a_h); 
    cudaFree(a_d); 


// time (&end); 
// dif=difftime(end,start); 

// printf ("\n\n"); 
// printf ("total time for this calculate is : %d second\n\n",(int)dif); 

} 

我註釋掉的時間部分。如果你喜歡,你可以取消註釋。時序不會令人印象深刻,因爲我們沒有使用GPU中的任何並行性。此外,這段代碼還有各種各樣的特性,其中最明顯的一點是我們只啓動一個線程,並且實際上使用GPU作爲串行機器。由於這不是執行GPU編程的方式,因此不應將其用作指導性示例。在CUDA SDK中有很多很好的GPU編程例子,以及網絡上的各種其他資源。

+0

感謝羅伯特。關於第一個問題我在這裏改變方法的名稱,忘記主要的方法的改變名稱。非常感謝您的全面解釋。它可以幫助我獲得更好的結果。 –