未处理的异常...访问冲突读取位置
Unhandled exception... Access Violation reading location
我正在学习使用 NVIDIA/CUDA/etc 的教程。这里:http://www.nvidia.com/content/gtc-2010/pdfs/2131_gtc2010.pdf
我正在尝试并行添加两个向量,但我遇到了 post.
标题中提到的这些内存访问违规问题
错误发生在我的 printf 行 (我将 post 我的代码在下面),但是如果我评论结果我被带到一个名为 "dbgheap.c" 的文件,我只是在该文件的第 1696 行收到相同的错误消息(该文件有 3268 行)
行是:
if (*pb++ != bCheck)
其中的函数是:
extern "C" static int __cdecl CheckBytes(
unsigned char * pb,
unsigned char bCheck,
size_t nSize
)
{
while (nSize--)
{
if (*pb++ != bCheck) //this is the line with the error
{
return FALSE;
}
}
return TRUE;
}
它说它无法访问的内存地址位置,我相信,是我的 "a"、"b" 和 "c" 变量的位置(将 post 我的代码如下)。
所以不用多说了,这是我的代码(抱歉,没有评论):
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#define N 10
__global__ void kernel() {
}
__global__ void add(int *a, int *b, int *c) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
void random_ints(int* a,int num) {
for (int i = 0; i<num; i++)
a[i] = rand();
}
int main () {
int *a,*b,*c;
int *dev_a, *dev_b, *dev_c;
int size = N*sizeof(int);
cudaMalloc((void**)&dev_a,size);
cudaMalloc((void**)&dev_b,size);
cudaMalloc((void**)&dev_c,size);
a = (int*)malloc(size);
b = (int*)malloc(size);
c = (int*)malloc(size);
random_ints(a,N);
random_ints(b,N);
cudaMemcpy(dev_a,&a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,&b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(&c,dev_c,size,cudaMemcpyDeviceToHost);
for (int i = 0; i<N; i++)
printf("%d + %d = %d\n",a[i],b[i],c[i]);
free(a); free(b); free(c);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
如果您需要任何说明,请直接询问。
谢谢!
cudaMemcpy 参数是实际的指针,因此在传递之前不需要获取它们的地址(与 cudaMalloc 不同)。删除 &.
cudaMemcpy(dev_a,a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(c,dev_c,size,cudaMemcpyDeviceToHost);
我相信这就是导致内存损坏问题的原因。
作为形式问题,我会传入长度并根据 blockIdx.x 进行检查。
__global__ void add(int *a, int *b, int *c, int N) {
if (blockIdx.x < N) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
}
我认为这实际上是必需的,但我猜如果范围适合单个扭曲则不需要。对于 N > 16,这将是必要的并且检查会稍微复杂一些(使用 threadIdx.x 和 blockDim.x)。
我正在学习使用 NVIDIA/CUDA/etc 的教程。这里:http://www.nvidia.com/content/gtc-2010/pdfs/2131_gtc2010.pdf
我正在尝试并行添加两个向量,但我遇到了 post.
标题中提到的这些内存访问违规问题错误发生在我的 printf 行 (我将 post 我的代码在下面),但是如果我评论结果我被带到一个名为 "dbgheap.c" 的文件,我只是在该文件的第 1696 行收到相同的错误消息(该文件有 3268 行)
行是:
if (*pb++ != bCheck)
其中的函数是:
extern "C" static int __cdecl CheckBytes(
unsigned char * pb,
unsigned char bCheck,
size_t nSize
)
{
while (nSize--)
{
if (*pb++ != bCheck) //this is the line with the error
{
return FALSE;
}
}
return TRUE;
}
它说它无法访问的内存地址位置,我相信,是我的 "a"、"b" 和 "c" 变量的位置(将 post 我的代码如下)。
所以不用多说了,这是我的代码(抱歉,没有评论):
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
#define N 10
__global__ void kernel() {
}
__global__ void add(int *a, int *b, int *c) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
void random_ints(int* a,int num) {
for (int i = 0; i<num; i++)
a[i] = rand();
}
int main () {
int *a,*b,*c;
int *dev_a, *dev_b, *dev_c;
int size = N*sizeof(int);
cudaMalloc((void**)&dev_a,size);
cudaMalloc((void**)&dev_b,size);
cudaMalloc((void**)&dev_c,size);
a = (int*)malloc(size);
b = (int*)malloc(size);
c = (int*)malloc(size);
random_ints(a,N);
random_ints(b,N);
cudaMemcpy(dev_a,&a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,&b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(&c,dev_c,size,cudaMemcpyDeviceToHost);
for (int i = 0; i<N; i++)
printf("%d + %d = %d\n",a[i],b[i],c[i]);
free(a); free(b); free(c);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
如果您需要任何说明,请直接询问。
谢谢!
cudaMemcpy 参数是实际的指针,因此在传递之前不需要获取它们的地址(与 cudaMalloc 不同)。删除 &.
cudaMemcpy(dev_a,a,size,cudaMemcpyHostToDevice);
cudaMemcpy(dev_b,b,size,cudaMemcpyHostToDevice);
add<<<N,1>>>(dev_a,dev_b,dev_c);
cudaMemcpy(c,dev_c,size,cudaMemcpyDeviceToHost);
我相信这就是导致内存损坏问题的原因。
作为形式问题,我会传入长度并根据 blockIdx.x 进行检查。
__global__ void add(int *a, int *b, int *c, int N) {
if (blockIdx.x < N) {
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
}
我认为这实际上是必需的,但我猜如果范围适合单个扭曲则不需要。对于 N > 16,这将是必要的并且检查会稍微复杂一些(使用 threadIdx.x 和 blockDim.x)。