Cuda 如何使用Cublas的恒定内存?
当我将cublasIsamax与常规内存分配器一起使用时,它工作得很好Cuda 如何使用Cublas的恒定内存?,cuda,cublas,Cuda,Cublas,当我将cublasIsamax与常规内存分配器一起使用时,它工作得很好 int FindMaxIndex( const float* pVector, const size_t length ) { int result = 0; float* pDevVector = nullptr; if( CUBLAS_STATUS_SUCCESS != ::cudaMalloc( (void**)&pDevVector, length * sizeof(float) )
int FindMaxIndex( const float* pVector, const size_t length )
{
int result = 0;
float* pDevVector = nullptr;
if( CUBLAS_STATUS_SUCCESS != ::cudaMalloc( (void**)&pDevVector, length * sizeof(float) ) )
{
return -1;
}
if( CUBLAS_STATUS_SUCCESS != ::cudaMemcpy( pDevVector, pVector, length * (int)sizeof(float), cudaMemcpyHostToDevice) )
{
return -2;
}
::cublasIsamax_v2( g_handle, length, pDevVector, 1, &result);
if( nullptr != pDevVector )
{
::cudaFree( pDevVector );
}
return result;
}
但如果尝试使用恒定内存,则会失败,出现未知错误N14。怎么了?
复制到常量内存成功,但执行失败
__constant__ float c_pIndex[ 255 ] = {0x00};
// the same function as GetIsMax but using CUBLAS function cublasIsamax_v2
int FindMaxIndexConst( const float* pVector, const size_t length, pfnMsg fnMsg )
{
int result = 0;
cudaError_t code = ::cudaMemcpyToSymbol( c_pIndex, pVector, length * sizeof(float), 0, cudaMemcpyHostToDevice );
if( cudaSuccess != code )
{
const char* szMsg = ::cudaGetErrorString ( code );
LogError3( L"[%d] [%hs] Could not allocate CUDA memory: %I64d pDevA", code, szMsg, (__int64)(length * sizeof(float)));
}
cublasStatus_t status = ::cublasIsamax_v2( g_handle, length, c_pIndex, 1, &result);
if( CUBLAS_STATUS_SUCCESS != status )
{
LogError2( L" [%d] Failed to execute <cublasIsamax_v2> : %I64d", status, (__int64)length );
}
return result;
}
\uuuu常量\uuuuu浮点c\u pIndex[255]={0x00};
//与GetIsMax函数相同,但使用CUBLAS函数cublasimax_v2
int FindMaxIndexConst(常量浮点*pVector,常量大小\u t长度,pfnMsg FNMG)
{
int结果=0;
cudaError_t code=::cudaMemcpyToSymbol(c_pIndex,pVector,length*sizeof(float),0,cudaMemcpyHostToDevice);
if(cudaSuccess!=代码)
{
const char*szMsg=::cudaGetErrorString(代码);
LogError3(L“[%d][%hs]无法分配CUDA内存:%I64d pDevA”,代码,szMsg,(uu int64)(长度*大小(浮点));
}
cublastatus_t status=::cublasamax_v2(g_句柄、长度、c_索引、1和结果);
if(CUBLAS_状态_成功!=状态)
{
LogError2(L“[%d]无法执行:%I64d”,状态,(\u int64)长度);
}
返回结果;
}
为什么不分配一个常规设备阵列并将其传递给CUBLAS
\uuuu常量\uuuu
数组不是正常的\uu设备\uuuu
数组。在代码中,获取数组的地址并将其传递给主机函数。主机上的阵列地址在设备上无效,反之亦然,如CUDA编程指南中所述。见:
通过获取\uuu设备\uuuu
、\uuu共享\uuuu
或\uu常量\uuuu
变量的地址获得的地址只能在设备代码中使用。通过设备内存中描述的cudaGetSymbolAddress()获取的\uuuu设备\uuuuuu
或\uuuuuuuuu常量\uuuuuuu
变量的地址只能在主机代码中使用
关于通过设备指针访问\uuuuuuu常量\uuuuuuu
内存,请参阅以了解其将被取消缓存的原因
最后,由于访问模式的原因,以这种方式使用
\uuuuuu常量\uuuuuu
内存(即使它缓存在常量缓存中)效率低下isamax
可能会访问每个线程中的不同内存位置,因此访问将被序列化。因此,这将比统一访问慢32倍(并且可能比常规设备内存慢得多) 为什么不分配一个常规设备阵列并将其传递给CUBLAS
\uuuu常量\uuuu
数组不是正常的\uu设备\uuuu
数组。在代码中,获取数组的地址并将其传递给主机函数。主机上的阵列地址在设备上无效,反之亦然,如CUDA编程指南中所述。见:
通过获取\uuu设备\uuuu
、\uuu共享\uuuu
或\uu常量\uuuu
变量的地址获得的地址只能在设备代码中使用。通过设备内存中描述的cudaGetSymbolAddress()获取的\uuuu设备\uuuuuu
或\uuuuuuuuu常量\uuuuuuu
变量的地址只能在主机代码中使用
关于通过设备指针访问\uuuuuuu常量\uuuuuuu
内存,请参阅以了解其将被取消缓存的原因
最后,由于访问模式的原因,以这种方式使用
\uuuuuu常量\uuuuuu
内存(即使它缓存在常量缓存中)效率低下isamax
可能会访问每个线程中的不同内存位置,因此访问将被序列化。因此,这将比统一访问慢32倍(并且可能比常规设备内存慢得多) 你不能像那样传递恒定的记忆。你不能像那样传递恒定的记忆。谢谢。现在我明白了。我刚刚在CublisSamax中使用c_pIndex重新实现了CublisSamax,效果很好。如果答案有用,请接受。但我想你没有看到我回答中解释为什么你所做的是个坏主意的部分。以这种方式使用恒定内存会很慢。谢谢。现在我明白了。我刚刚在CublisSamax中使用c_pIndex重新实现了CublisSamax,效果很好。如果答案有用,请接受。但我想你没有看到我回答中解释为什么你所做的是个坏主意的部分。以这种方式使用常量内存会很慢。