我有两个矩阵(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;
}