我想知道为什么我的前几千个结果是正确的,然后我在cuda编程中得到了旧的值? #包括“opencv2\opencv.hpp” #包括 #包括 #包括 使用名称空间cv; 使用名称空间std; #定义计数200000 __全球的__ 无效子阵列(int*a、int*b、int-size) { int id=blockIdx.x*blockDim.x+threadIdx.x; 如果(id
当我的内核运行时,它首先给出几个值,即差值正确,然后开始显示旧值?我做错了什么?我是noob,虽然我认为这些是我选错的块和线程的数量。我想知道为什么我的前几千个结果是正确的,然后我在cuda编程中得到了旧的值? #包括“opencv2\opencv.hpp” #包括 #包括 #包括 使用名称空间cv; 使用名称空间std; #定义计数200000 __全球的__ 无效子阵列(int*a、int*b、int-size) { int id=blockIdx.x*blockDim.x+threadIdx.x; 如果(id,opencv,cuda,nvidia,Opencv,Cuda,Nvidia,当我的内核运行时,它首先给出几个值,即差值正确,然后开始显示旧值?我做错了什么?我是noob,虽然我认为这些是我选错的块和线程的数量。 我的gpu CC是3.2您的代码中至少有2个错误 如前所述,内核假设每个像素有1个线程。您必须启动足够的线程来覆盖图像中的所有像素。我们可以通过增加块数来解决这个问题 您使用的复制操作的大小不正确。image1和image2数组都指定为int数组,内核相应地接受int*参数。您(显然)加载了一个无符号字符图像,但在加载该图像的过程中,您已将每个像素从8位量转换为
我的gpu CC是3.2您的代码中至少有2个错误
image1
和image2
数组都指定为int
数组,内核相应地接受int*
参数。您(显然)加载了一个无符号字符
图像,但在加载该图像的过程中,您已将每个像素从8位量转换为32位量:
#include "opencv2\opencv.hpp"
#include <stdint.h>
#include <stdio.h>
#include <cuda.h>
using namespace cv;
using namespace std;
#define count 200000
__global__
void SubArrays(int * a, int * b, int size)
{
int id = blockIdx.x * blockDim.x + threadIdx.x;
if (id < size)
{
a[id] -= b[id];
}
}
int image1[count];
int image2[count];
int main(int argv, char** argc)
{
Mat im1 = imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat im2 = imread("2.jpg", CV_LOAD_IMAGE_GRAYSCALE);
int size = (im1.rows*im1.cols);
printf("size: %d \n\n\n\n", size);
int i = 0;
for (int r = 0; r < im1.rows; r++)
{
for (int c =0; c< im1.cols; c++,i++)
{
image1[i] = im1.at<uint8_t>(r, c);
image2[i] = im2.at<uint8_t>(r, c);
}
}
printf("This is first image array's first 5 elements\n\n");
for (int b = 0; b < 5; b++)
{
printf("%d\n",image1[b]);
}
printf("This is second image array's first 5 elements\n\n");
for (int b = 0; b < 5; b++)
{
printf("%d\n", image2[b]);
}
int * h_a = image1;
int * h_b = image2;
int * d_a;
int * d_b;
cudaMalloc(&d_a, sizeof(char)*size);
cudaMalloc(&d_b, sizeof(char)*size);
cudaMemcpy(d_a, h_a, sizeof(char)*size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, sizeof(char)*size, cudaMemcpyHostToDevice);
SubArrays << <1, 1024 >> >(d_a, d_b, size);
cudaMemcpy(h_a, d_a, sizeof(char)*size, cudaMemcpyDeviceToHost);
printf("calculating result\n\n");
for (int check = 0; check < size ; check++)
{
printf("%d \n", h_a[check]);
}
cudaFree(d_a);
cudaFree(d_b);
return 0;
}
sizeof(char)
的使用不正确。您现在正在处理int
数量,您应该在任何地方使用sizeof(int)
cudaMemcpy(d_a, h_a, sizeof(char)*size, cudaMemcpyHostToDevice);
^^^^^^^^^^^
$cat t1222.cu
#包括
#包括
使用名称空间std;
#定义计数200000
__全球的__
无效子阵列(int*a、int*b、int-size)
{
int id=blockIdx.x*blockDim.x+threadIdx.x;
如果(id<大小)
{
a[id]=b[id];
}
}
int image1[计数];
int image2[计数];
int main(int argv,字符**argc)
{
int i=0;
对于(i=0;i(d_a、d_b、大小);
cudaMemcpy(h_a,d_a,sizeof(int)*size,cudamemcpydevicetoost);
printf(“计算结果\n\n”);
for(int check=0;check
我始终建议您在CUDA代码出现问题时使用(尽管我没有在此处添加它),并使用
CUDA memcheck
(如上所述)运行代码。TL/DR。听起来像是某个地方的整数溢出。为什么您只运行1024个线程的1个块?如果图像超过1024像素,那么大量的图像将未经处理。首先了解CUDA不是C!不要添加错误的标记。@talonmes那么我应该使用多少块和线程?我的图像大小约为340*507,接近2 lac。@Olaf好的,先生,我很抱歉,先生,这真的帮了我的忙!!解释得很透彻!!多谢各位
cudaMemcpy(d_a, h_a, sizeof(char)*size, cudaMemcpyHostToDevice);
^^^^^^^^^^^
$ cat t1222.cu
#include <stdint.h>
#include <stdio.h>
using namespace std;
#define count 200000
__global__
void SubArrays(int * a, int * b, int size)
{
int id = blockIdx.x * blockDim.x + threadIdx.x;
if (id < size)
{
a[id] -= b[id];
}
}
int image1[count];
int image2[count];
int main(int argv, char** argc)
{
int i = 0;
for (i = 0; i < count; i++)
{
image1[i] = 3;
image2[i] = 1;
}
int size = count;
printf("This is first image array's first 5 elements\n\n");
for (int b = 0; b < 5; b++)
{
printf("%d\n",image1[b]);
}
printf("This is second image array's first 5 elements\n\n");
for (int b = 0; b < 5; b++)
{
printf("%d\n", image2[b]);
}
int * h_a = image1;
int * h_b = image2;
int * d_a;
int * d_b;
cudaMalloc(&d_a, sizeof(int)*size);
cudaMalloc(&d_b, sizeof(int)*size);
cudaMemcpy(d_a, h_a, sizeof(int)*size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, sizeof(int)*size, cudaMemcpyHostToDevice);
SubArrays << <(count + 1023)/1024, 1024 >> >(d_a, d_b, size);
cudaMemcpy(h_a, d_a, sizeof(int)*size, cudaMemcpyDeviceToHost);
printf("calculating result\n\n");
for (int check = 0; check < size ; check++)
{
if (h_a[check] != 2){printf("mismatch at %d, was: %d should be 2\n", check, h_a[check]); return -1;}
}
printf("Success!\n");
cudaFree(d_a);
cudaFree(d_b);
return 0;
}
$ nvcc -o t1222 t1222.cu
$ cuda-memcheck ./t1222
========= CUDA-MEMCHECK
This is first image array's first 5 elements
3
3
3
3
3
This is second image array's first 5 elements
1
1
1
1
1
calculating result
Success!
========= ERROR SUMMARY: 0 errors
$