【问题标题】:Unhandled exception... Access Violation reading location未处理的异常...访问冲突读取位置
【发布时间】:2015-05-01 14:59:43
【问题描述】:

我正在学习使用 NVIDIA/CUDA/etc 的教程。这里:http://www.nvidia.com/content/gtc-2010/pdfs/2131_gtc2010.pdf

我正在尝试并行添加两个向量,但我遇到了帖子标题中提到的这些内存访问违规问题。

错误发生在我的 printf 行 (我将在下面发布我的代码),但如果我将其注释掉,我会被带到一个名为 的文件“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”变量的位置(将在下面发布我的代码)。

所以不用多说,这是我的代码(抱歉没有 cmets):

#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;
}

如果您需要任何澄清,请尽管询问。

谢谢!

【问题讨论】:

  • add&lt;&lt;&lt;N,1&gt;&gt;&gt;(dev_a,dev_b,dev_c); 是什么意思?你确定你知道吗?另外,不要转换 malloc() 的返回值,而是检查它是否不返回 NULL
  • 它告诉 add() 并行运行 N 次。

标签: c visual-studio-2010 cuda gpu


【解决方案1】:

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)。

【讨论】:

  • 谢谢!!这实际上很有意义! (我刚刚回到教程幻灯片并意识到他们在移动到并行加法示例时取出了“&”)。直到明天我才能使用这台机器,但如果这不能解决它,我会感到震惊。再次感谢! :)
猜你喜欢
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2011-09-28
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多