1

我有两个矩阵(A 和 B),二维。而且我认为如果不是将其放入全局内存并通过指针访问,我会加快速度,而是将它们放入纹理 2d 并使用它。矩阵不是那么大,不同的线程读取不同的位置。

所以现在我的代码正在使用全局内存,我得到的值是正确的,我正在乘以矩阵中的每个值:

A[i][j] * B[ p[i] ] [ p[j] ]

我正在测试的实例的最佳值是9552,不能得到不同的值。

所以我进入了纹理,似乎有些获取返回了错误的值,因为我9511现在得到了一个。

我在 CUDA 上搜索纹理,我看到它们被 [0..n-1] 索引。但是他们有一些规范化的访问,还有一些其他的东西,比如过滤,你想要的值是邻居的插值。

纹理的默认选项是什么?也许这就是问题所在。在编程指南中找不到默认值。

这是相关代码:

宣言:

texture<float,2> A_matrix;
texture<float,2> B_matrix;

分配:

HANDLE_ERROR( cudaMalloc( (void**)&_A, n * n * sizeof(float) ) );
HANDLE_ERROR( cudaMalloc( (void**)&_B, n * n * sizeof(float) ) );

内存

HANDLE_ERROR( cudaMemcpy( _A, A, n * n * sizeof(float), cudaMemcpyHostToDevice ) );
HANDLE_ERROR( cudaMemcpy( _B, B, n * n * sizeof(float), cudaMemcpyHostToDevice ) );

绑定和描述符(创建了两个,因为我很傻)

cudaChannelFormatDesc desc = cudaCreateChannelDesc<float>();
    cudaChannelFormatDesc desc2 = cudaCreateChannelDesc<float>();

    HANDLE_ERROR( cudaBindTexture2D( NULL, A_matrix,
                                   _A,
                                   desc, n, n,
                                   sizeof(float) * n ) );
    HANDLE_ERROR( cudaBindTexture2D( NULL, B_matrix,
                                   _B,
                                   desc2, n, n,
                                   sizeof(float) * n ) );

我在哪里使用它

res += tex2D(A_matrix, i, j)  * tex2D(B_matrix, p[i], p[j]);

那么如何正确使用纹理呢?还是他们注定要这样?

编辑:

这是使用此内存访问的代码,注释行不使用纹理,并且工作正常。

__device__ inline float datastruct::getPermutationValue(int* p)
{
    float res = 0;
    for(int i = 0 ; i < ints[data_n] ; i++)
        for(int j = 0 ; j < ints[data_n] ; j++)
            res += tex2D(A_matrix, i, j)  * tex2D(B_matrix, p[i], p[j]);
            //res += qap_A[i * ints[data_n] + j]  * qap_B[p[i] * ints[data_n] + p[j]];
    return res;
}
4

2 回答 2

1

纹理源于对图形的需求,因此标准定义了一些特质。在这种情况下,您可能会遇到与您提供的坐标有关的问题,因为您没有找到准确的点。尝试这个:

res += tex2D(A_matrix, i+0.5f, j+0.5f)  * tex2D(B_matrix, p[i]+0.5f, p[j]+0.5f);

顺便说一句,您应该考虑使用倾斜内存或 CUDA 阵列来提高性能,有关详细信息,请参阅 CUDA 编程指南和参考手册。

于 2010-11-26T09:44:36.953 回答
1

抱歉,CUDA 中的 2D 纹理可能会很痛苦。我有一个简单的代码,只有大约 150 行。我把它贴在了英伟达论坛上。我相信您可能需要其中一个 sdk 库来编译。对于更复杂的操作,我对纹理没有太多的运气。我希望这对你有帮助,它应该为你编译。

于 2010-11-28T21:57:23.720 回答