为什么以下 POP 功能无法在主机或设备 (CUDA) 上运行?

why the following pop function can't work on host or device (cuda)?

本文关键字:CUDA 运行 主机 POP 功能 为什么      更新时间:2023-10-16

为什么代码中的函数pop((不能在全局内核或使用cuda编程中的主机线程运行,而其他函数都可以?我调试了很长时间,但没有发现任何错误。有人能说出原因吗?

#define N 10
//define a vector for new or delete dynamically
template<typename T>
class LocalVector
{
private:
T* m_begin;
T* m_end;
size_t capacity;
size_t length;
__host__ __device__ void expand() {
capacity *= 2;
size_t tempLength = (m_end - m_begin);
T* tempBegin = new T[capacity];
memcpy(tempBegin, m_begin, tempLength * sizeof(T));
delete[] m_begin;
m_begin = tempBegin;
m_end = m_begin + tempLength;
length = static_cast<size_t>(m_end - m_begin);
}
public:
__host__ __device__  explicit LocalVector() : length(0), capacity(15) {
m_begin = new T[capacity];
m_end = m_begin;
}
__host__ __device__ T& operator[] (unsigned int index) {
return *(m_begin + index);
}
__host__ __device__ T* begin() {
return m_begin;
}
__host__ __device__ T* end() {
return m_end;
}
__host__ __device__ ~LocalVector()
{
delete[] m_begin;
m_begin = nullptr;
}
__host__ __device__ void add(T t) {
if ((m_end - m_begin) >= capacity) {
expand();
}
new (m_end) T(t);
m_end++;
length++;
}
__host__ __device__ T pop() {
T endElement = (*m_end);
delete m_end;
m_end--;
return endElement;
}
__host__ __device__ size_t getSize() {
return length;
}
};
//cuda kernel function
__global__ void addKernel(LocalVector<int> *c)
{
int i = threadIdx.x;
c->pop();
}
//main function
int main() {
cudaSetDevice(0);
LocalVector<int> hlv;
for (int i = 0; i < N; i++) {
hlv.add(i*2);
}
hlv.pop();//can't work,and stop running
printf("n");
for (int i = 0; i < hlv.getSize(); i++) {
printf("hlv[%d]=%d,", i,hlv[i]);
}
return 0;
}

当你pop时,你不应该delete任何东西,当expanddelete时,你只应该delete整个内部数组在析构函数时。此更改将修复:

void add(T t) {
if ((m_end - m_begin) >= capacity) {
expand();
}
*(m_begin + length) = t;
m_end++;
length++;
}
T pop() {
T endElement = (*m_end);
m_end--;
return endElement;
}
long long  getSize() {
return length;
}

Godbolt 直播