在win7 64bit中设置tdrlevel cuda时出现错误结果

时间:2012-09-29 04:56:34

标签: cuda

当我在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)

我不知道问题出在哪里。我的块的数量是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);

}

1 个答案:

答案 0 :(得分:1)

此代码有几个问题。例如,一个问题是您使用名称fibunat_array定义内核,但是您调用名为square_array的内核。因此,您发布的代码甚至无法正确编译。另一个问题是你的内核是从串行代码解决问题的角度编写的,没有考虑并行运行线程。启动内核时创建的每个线程都将运行完全相同的代码。如果使用多个线程/块,这将不起作用,并且不是利用机器的好方法。

您似乎想要计算斐波纳契序列中的前100个数字。您可能想要考虑这一点的含义。这page可能会有所帮助。例如,此序列范围中的一些最大数字将不适合64位整数。对于32位代码,在序列中大约47个数字后,无符号整数大小将太小。此外,创建并行斐波纳契生成器可能需要一种与您想到的串行算法不相似的算法。

即使你确实创建了一个并行的fibonacci生成器,让我们假设每个线程都计算了该系列的1个元素,你就可以在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编程示例,以及网络上的各种其他资源。