我有两个矩阵(A和B),2维。而且我认为如果不是将其放入全局内存并通过指针访问,我会加速一点,我将它们放入纹理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) ) );
的memcpy
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;
}
答案 0 :(得分:1)
纹理源于图形中的需求,因此标准定义了一些特性。在这种情况下,您可能遇到了所提供坐标的问题,因为您没有达到确切的点。试试这个:
res += tex2D(A_matrix, i+0.5f, j+0.5f) * tex2D(B_matrix, p[i]+0.5f, p[j]+0.5f);
顺便提一下,您应该考虑使用音调内存或CUDA阵列来提高性能,有关详细信息,请参阅“CUDA编程指南”和“参考手册”。
答案 1 :(得分:1)
抱歉,CUDA中的2D纹理可能很痛苦。我有一个简单的代码,只有大约150行。我把它发布在nvidia forums上。我相信你可能需要一个sdk库来编译。对于更复杂的操作,我没有太多运气纹理。我希望这可以帮助你,它应该为你编译。