У меня есть две матрицы (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) ) );
тетср
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]);
Так как я могу правильно использовать текстуры? Или они должны быть такими?
EDIT:
Это код, который использует этот доступ к памяти, закомментированная строка не использует текстуры и РАБОТАЕТ ОТЛИЧНО.
__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;
}