Linux GPU上使用单线程内核的奇偶排序行为 \uuuuu全局\uuuuu无效排序\u单个(int*size,int*arr){ 用于(int m=0;m

Linux GPU上使用单线程内核的奇偶排序行为 \uuuuu全局\uuuuu无效排序\u单个(int*size,int*arr){ 用于(int m=0;m,linux,sorting,cuda,Linux,Sorting,Cuda,这是CUDA GPU的内核代码。它进行奇偶排序。 为了调用它,我在准备好所有数据后从main使用它。 sort_single(d_a,d_b); 我的问题是,为什么它在这里给出不正确的结果,而如果我将此代码作为常规C/C++函数代码运行,它会给出正确的结果 __global__ void sort_single(int *size , int *arr){ for ( int m = 0; m < *size / 2; m++) { for (int i = 0; i <

这是CUDA GPU的内核代码。它进行奇偶排序。 为了调用它,我在准备好所有数据后从main使用它。
sort_single(d_a,d_b);
我的问题是,为什么它在这里给出不正确的结果,而如果我将此代码作为常规C/C++函数代码运行,它会给出正确的结果

__global__ void sort_single(int *size , int *arr){
for ( int m = 0; m < *size / 2; m++)
{
    for (int  i = 0; i < *size; i += 2)
    {
        if (arr[i + 1] > arr[i])
        {
            int temp = arr[i];
            arr[i] = arr[i + 1];
            arr[i + 1] = temp;
        }
    }
    /*for (int i = 0; i < size; i++)
    printf("%d ", arr[i]);
    printf("\n");*/
    for ( int i = 1; i < *size; i += 2)
    {
        if (arr[i + 1] > arr[i])
        {
            int temp = arr[i];
            arr[i] = arr[i + 1];
            arr[i + 1] = temp;
        }
    }
 }
}
for(int m=0;m
我在这里也在做同样的事情 我认为它与这个算法所需的步骤数有关,例如,每次迭代需要2个步骤

  • 将偶数索引与下一个索引进行比较

  • 将奇数索引与下一个索引进行比较

  • 由于我使用的是单个GPU线程,所以当您增加阵列中的元素数时,我无法理解为什么会发生这种情况。我需要澄清GPU单线程与CPU的区别,以便了解当前的行为。

    以下是文件内容:

    for ( int m = 0; m < N / 2; m++)
    sort_single<<<1,1>>>(d_a,d_b);
    
    #包括“stdio.h”
    __全局无效添加(int*a、int*b、int*c){
    c[blockIdx.x]=a[blockIdx.x]+b[blockIdx.x];
    }
    __全局无效排序单个(int*size,int*arr){
    用于(int m=0;m<*size/2;m++)
    {   
    对于(int i=0;i<*大小;i+=2)
    {
    如果(arr[i+1]>arr[i])
    {
    int temp=arr[i];
    arr[i]=arr[i+1];
    arr[i+1]=温度;
    }
    }
    /*对于(int i=0;iarr[i])
    {
    int temp=arr[i];
    arr[i]=arr[i+1];
    arr[i+1]=温度;
    }
    }
    }
    }
    无效随机整数(整数*a,整数N)
    {
    int i;
    对于(i=0;i1)
    {
    N=atoi(argv[1]);
    }
    int*a,*b;
    int*d_a,*d_b;
    int-isize=N*sizeof(int);
    a=(int*)malloc(sizeof(int));a[0]=N;
    b=(int*)malloc(isize);统一整数(b,N);
    cudaError\u t cudaStatus;
    //选择要在哪个GPU上运行,在多GPU系统上更改此选项。
    cudaStatus=cudaSetDevice(0);
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudaSetDevice失败!是否安装了支持CUDA的GPU?”);
    转到错误;
    }
    cudaStatus=cudamaloc((void**)和d_a,sizeof(int));
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudamaloc失败!”);
    转到错误;
    }
    cudaStatus=cudamaloc((void**)和d_b,isize);
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudamaloc失败!”);
    转到错误;
    }    
    cudaStatus=cudaMemcpy(d_a,a,sizeof(int),cudamemcpyhostodevice);
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudaMemcpy失败!”);
    转到错误;
    }
    cudaStatus=cudaMemcpy(d_b,b,isize,cudamemcpyhostodevice);
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudaMemcpy失败!”);
    转到错误;
    }
    分类单(d_a,d_b);
    //检查启动内核时是否有任何错误
    cudaStatus=cudaGetLastError();
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“addKernel启动失败:%s\n”,cudaGetErrorString(cudaStatus));
    转到错误;
    }
    //cudaDeviceSynchronize等待内核完成,然后返回
    //在启动过程中遇到的任何错误。
    cudaStatus=cudaDeviceSynchronize();
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudaDeviceSynchronize在启动addKernel!\n后返回错误代码%d”,cudaStatus);
    转到错误;
    }
    cudaStatus=cudaMemcpy(b、d_b、isize、cudaMemcpyDeviceToHost);
    if(cudaStatus!=cudaSuccess){
    fprintf(stderr,“cudaMemcpy失败!”);
    转到错误;
    }
    对于(int i=0;i
    该代码使用简单的C/C++函数以及cuda内核进行编译,因为它基于数组大小均匀的假设。它给出了正确的结果,错误是mallocking。无论如何,感谢您的回复。

    请在您的问题中编辑一个适当的标题。很难或不可能说出out-on的错误。在可能出现的其他问题中,您的代码将在此行进行非法越界访问(在奇数中,即第二次扫描,如果总体大小为偶数):
    if(arr[i+1]>arr[i])
    。使用
    cuda memcheck
    运行代码。由于for循环增加到
    *大小
    [i+1]
    将索引超出范围。这只是一个破译的代码,并且不是CPU或GPU实现所独有的。@Talonmes另一个代码实际上是文件的可编译代码,您可以使用nvcc下载和编译。我不知道为什么它会显示内容,也不知道如何关闭它们。@RobertCrovella抱歉,我没有提到它,但我目前只对文件中的偶数个元素执行此操作A.
    #include "stdio.h"
    __global__ void add(int *a , int *b ,int*c){
    
            c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
    
    }
    __global__ void sort_single(int *size , int *arr){
    
        for ( int m = 0; m < *size / 2; m++)
        {   
            for (int  i = 0; i < *size; i += 2)
            {
                if (arr[i + 1] > arr[i])
                {
                    int temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
    
                }
            }
            /*for (int i = 0; i < size; i++)
            printf("%d ", arr[i]);
            printf("\n");*/
            for ( int i = 1; i < *size; i += 2)
            {
                if (arr[i + 1] > arr[i])
                {
                    int temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
    
                }
            }
    
        }
    
    }
    void random_ints(int *a, int N)
    {
       int i;
       for (i = 0; i < N; ++i)
        a[i] = rand() %5000;
    }
    void uniform_ints(int *a, int N)
    {
       int i;
       for (i = 0; i < N; ++i)
        a[i] = i+1;
    
    }
    
    int main(int argc , char**argv){
        int N = 8;
        if(argc>1)
          {
              N=atoi(argv[1]);
          }
        int *a , *b  ;
        int *d_a , *d_b ;
        int isize = N * sizeof(int);
    
        a = (int *)malloc(sizeof(int));a[0] = N;
        b = (int *)malloc(isize);uniform_ints(b , N);
    
    
        cudaError_t cudaStatus;
        // Choose which GPU to run on, change this on a multi-GPU system.
        cudaStatus = cudaSetDevice(0);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
            goto Error;
        }
        cudaStatus = cudaMalloc((void**)&d_a,sizeof(int));
    
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMalloc failed!");
            goto Error;
        }
        cudaStatus = cudaMalloc((void**)&d_b,isize);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMalloc failed!");
            goto Error;
        }    
    
        cudaStatus = cudaMemcpy(d_a, a , sizeof(int),cudaMemcpyHostToDevice);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
            goto Error;
        }
        cudaStatus = cudaMemcpy(d_b, b , isize,cudaMemcpyHostToDevice);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
            goto Error;
        }
    
        sort_single<<<1,1>>>(d_a,d_b);
        // Check for any errors launching the kernel
        cudaStatus = cudaGetLastError();
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
            goto Error;
        }
    
        // cudaDeviceSynchronize waits for the kernel to finish, and returns
        // any errors encountered during the launch.
        cudaStatus = cudaDeviceSynchronize();
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
            goto Error;
        }
    
        cudaStatus = cudaMemcpy(b, d_b , isize,cudaMemcpyDeviceToHost);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
            goto Error;
        }
        for (int i = 0; i < N; i++)
            printf("%d ", b[i]);
        printf("\n");
        Error:
        cudaFree(d_a);
        cudaFree(d_b);
        return cudaStatus;
    }