在cuda代码中,我试图使用结构和常量结构对象,并使用cudaMemcpyToSymbol将值赋给常量对象,但不访问此常量值。我知道常量的实际使用不是这种方式,因为每个线程需要访问不同的值并且不能利用内存广播到半翘曲但是在某些情况下我需要这种方式
#include <iostream>
#include <stdio.h>
#include <cuda.h>
using namespace std;
struct CDistance
{
int Magnitude;
int Direction;
};
__constant__ CDistance *c_daSTLDistance;
__global__ static void CalcSTLDistance_Kernel(CDistance *m_daSTLDistance)
{
int ID = threadIdx.x;
m_daSTLDistance[ID].Magnitude = m_daSTLDistance[ID].Magnitude + c_daSTLDistance[ID].Magnitude ;
m_daSTLDistance[ID].Direction = 2 ;
}
// main routine that executes on the host
int main(void)
{
CDistance *m_haSTLDistance,*m_daSTLDistance;
m_haSTLDistance = new CDistance[10];
for(int i=0;i<10;i++)
{
m_haSTLDistance[i].Magnitude=3;
m_haSTLDistance[i].Direction=2;
}
//m_haSTLDistance =(CDistance*)malloc(100 * sizeof(CDistance));
cudaMalloc((void**)&m_daSTLDistance,sizeof(CDistance)*10);
cudaMemcpy(m_daSTLDistance, m_haSTLDistance,sizeof(CDistance)*10, cudaMemcpyHostToDevice);
cudaMemcpyToSymbol(c_daSTLDistance, m_haSTLDistance, sizeof(m_daSTLDistance)*10);
CalcSTLDistance_Kernel<<< 1, 100 >>> (m_daSTLDistance);
cudaMemcpy(m_haSTLDistance, m_daSTLDistance, sizeof(CDistance)*10, cudaMemcpyDeviceToHost);
for (int i=0;i<10;i++){
cout<<m_haSTLDistance[i].Magnitude<<endl;
}
free(m_haSTLDistance);
cudaFree(m_daSTLDistance);
}
在输出中,在内核中不访问常量c_daSTLDistance [ID] .Magnitude,并且获得静态赋值3,而我希望将此设备值3添加到常量值并返回总计6。
在查看cuda-memcheck时,它表示读取操作错误,内存超出绑定
答案 0 :(得分:2)
由于使用c_daSTLDistance
时未初始化的指针/缓冲区溢出问题,您的代码无效。这样做是违法的:
__constant__ CDistance *c_daSTLDistance;
....
cudaMemcpyToSymbol(c_daSTLDistance, m_haSTLDistance, sizeof(m_daSTLDistance)*10);
没有为每个分配的内存或为c_daSTLDistance
设置有效值。
此外,请注意,必须静态定义所有常量内存变量,并且无法在运行时动态分配常量内存。因此,您尝试做的事情无法发挥作用。另请注意,除了最古老的CUDA设备外,内核参数都存储在常量内存中。因此,如果你有一个非常小的常量结构数组,那么通过值传递给内核会更容易和更简单。编译器和运行时将自动将它们放在常量内存中,而无需任何显式的主机API调用。