这个问题是关于CUDA堆大小限制。 我曾参观过有关这个话题的一些问题,包括这一个: 在内核中新的运营商..奇怪的行为,我做了一些测试。 给定一个内核如下:
#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;
}
我想测试堆大小限制。
- 动态地分配一个阵列(温度)与一种螺纹,其大小大约是超过96万*的sizeof(双)(接近8MB,这是堆大小的缺省极限)给出一个错误:确定。 900000幅作品。 (没有人知道如何计算真正的限制吗?)
- 上升堆的大小限制允许分配更多的内存:正常,确定。
- 回到一个8MB堆大小,分配每个线程一个阵列与两个线程(因此,如果替换(I == 0)如果由(ⅰ== 0 ||我== 1),每一个900000 *的sizeof(双)失败但45万*的sizeof(双)各自的作品。还行。
- 这里说到我的问题:有一个线程(因此,温度和TEMP2线程0)分配两个阵列,每个阵列900000 *的sizeof(双)工作过,但它不应该? 事实上,当我尝试在两个数组来写,它失败。 但是,任何人都使用同一个线程,而不是两个阵列,两个线程两个数组时有一个想法,为什么在这个分配不同的行为?
编辑:另一个测试,我觉得这对于那些谁像我一样,会学习堆的使用有趣:5.执行内核的两倍,大小为90万*的sizeof(双)由单个线程0分配的一个阵列,如果有删除的作品。 如果删除被省略,它会失败,第二次,但在第一次调用将被执行。
编辑2:如何通过所有线程一次,但可写分配设备范围内的变量(不是从主机上,使用在设备代码动态分配)?