Нужна помощь с 2D текстурами на CUDA. Не получается ожидаемое значение для индексов, которые я хочу - PullRequest
1 голос
/ 26 ноября 2010

У меня есть две матрицы (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;
}

Ответы [ 2 ]

1 голос
/ 29 ноября 2010

Извините, 2D текстуры в CUDA могут быть болезненными.У меня есть простой код, который всего около 150 строк.Я разместил это на форумах nvidia .Я считаю, что вам может понадобиться одна из библиотек SDK для компиляции.Мне не слишком повезло с текстурами для более сложных операций.Надеюсь, это поможет вам, оно должно скомпилироваться для вас.

1 голос
/ 26 ноября 2010

Текстуры рождаются из-за потребности в графике, и поэтому существуют определенные особенности, определенные стандартами. В этом случае вы, вероятно, столкнулись с проблемой с указанными вами координатами, поскольку вы не достигли точной точки. Попробуйте это:

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

Между прочим, вам следует рассмотреть возможность использования тональной памяти или массивов CUDA для повышения производительности, см. Руководство по программированию CUDA и Справочное руководство для получения дополнительной информации.

...