Cuda 如何使用Cublas的恒定内存?

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) )

当我将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) ) )
    {
        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,效果很好。如果答案有用,请接受。但我想你没有看到我回答中解释为什么你所做的是个坏主意的部分。以这种方式使用常量内存会很慢。