Linux GPU上使用单线程内核的奇偶排序行为 \uuuuu全局\uuuuu无效排序\u单个(int*size,int*arr){ 用于(int m=0;m
这是CUDA GPU的内核代码。它进行奇偶排序。 为了调用它,我在准备好所有数据后从main使用它。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 <
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个步骤
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;
}