-2

当我在 cuda 上计算时,这是真的,但是当我使用更大的数字进行计算时,我必须将 TdrLevel 设置为
这个链接 。但是在设置 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-4316080-431602080-431602080-431602080-431602080-431602080-431602080208020802080208021616020802002020802161602161616161616161616020802020802020202020200202161602020200202602026020202026020260转

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

}
4

1 回答 1

1

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

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

即使您确实创建了一个并行斐波那契生成器,并且假设每个线程计算该系列的 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 编程示例,以及网络上的各种其他资源。

于 2012-10-06T02:39:12.297 回答