【发布时间】:2013-07-29 12:56:23
【问题描述】:
这个问题是关于 cuda 中的堆大小限制的。 访问了有关此主题的一些问题,包括以下问题: new operator in kernel .. strange behaviour 我做了一些测试。给定一个内核如下:
#include <cuda.h>
#include <cuda_runtime.h>
#define CUDA_CHECK( err ) __cudaSafeCall( err, __FILE__, __LINE__ )
#define CUDA_CHECK_ERROR() __cudaCheckError( __FILE__, __LINE__ )
inline void __cudaSafeCall( cudaError err, const char *file, const int line )
{
if ( cudaSuccess != err )
{
fprintf( stderr, "cudaSafeCall() failed at %s:%i : %s\n",
file, line, cudaGetErrorString( err ) );
exit( -1 );
}
return;
}
inline void __cudaCheckError( const char *file, const int line )
{
cudaError err = cudaGetLastError();
if ( cudaSuccess != err )
{
fprintf( stderr, "cudaCheckError() failed at %s:%i : %s\n",
file, line, cudaGetErrorString( err ) );
exit( -1 );
}
return;
}
#include <stdio>
#define NP 900000
__device__ double *temp;
__device__ double *temp2;
__global__
void test(){
int i = blockDim.x*blockIdx.x + threadIdx.x;
if(i==0){
temp = new double[NP];
//temp2 = new double[NP];
}
if(i==0){
for(int k=0;k<NP;k++){
temp[i] = 1.;
if(k%1000 == 0){
printf("%d : %g\n", k, temp[i]);
}
}
}
if(i==0){
delete(temp);
//delete(temp2);
}
}
int main(){
//cudaDeviceSetLimit(cudaLimitMallocHeapSize, 32*1024*1024);
//for(int k=0;k<2;k++){
test<<<ceil((float)NP/512), 512>>>();
CUDA_CHECK_ERROR();
//}
return 0;
}
我想测试堆大小限制。
- 用一个线程动态分配一个数组(temp),大小为 大约超过 960,000*sizeof(double)(接近 8MB,这是 堆大小的默认限制)给出错误:好的。 900,000 件作品。 (有人知道如何计算真正的极限吗?)
- 提高堆大小限制允许分配更多内存:正常,可以。
- 回到 8MB 堆大小,为每个线程分配一个数组和两个线程(因此,将 if (i==0) 替换为 if(i==0 || i==1),每个线程 900,000 * sizeof( double) 失败。但是每个 450,000*sizeof(double) 都可以。仍然可以。
- 我的问题来了:用一个线程分配两个数组(因此,线程 0 的 temp 和 temp2),每个 900,000 * sizeof(double) 也可以,但它不应该吗?事实上,当我尝试在两个数组中写入时,它都会失败。但是任何人都知道为什么在使用带有一个线程的两个数组而不是带有两个线程的两个数组时会出现这种不同的分配行为?
编辑:另一个测试,我觉得对于像我一样学习堆用法的人来说很有趣: 5. 内核执行两次,单线程0分配一个大小为900,000 * sizeof(double)的数组,如果有delete就可以了。如果省略delete,第二次会失败,但会执行第一次调用。
编辑 2:如何分配设备范围的变量一次但可由所有线程写入(不是来自主机,在设备代码中使用动态分配)?
【问题讨论】:
-
你能把你的代码和你的描述集中在你认为你正在观察的问题上吗?你能提供一个完整的,可编译的代码吗?它不应该很长。您如何测试
new操作的成功/失败?通常的测试是检查返回的指针是否为零,但我在代码中的任何地方都看不到。 -
停止用新问题编辑问题。让人无法回答。这不是聊天论坛。
-
我正在通过 printf 的返回进行测试,失败是由 cudaerror: unspecified launch failure 引起的。我编辑了可编译的代码。
标签: cuda heap-memory