У меня есть очень простой пример ядра cuda, который добавляет соответствующие строки из двух матриц. У меня вопрос о доступе к памяти в матрицах. Я вызываю ядро через mexfunction. Мы знаем, что в Matlab мы имеем доступ к порядку в столбце, а в C/C++ - порядок строк. Основанный на организации памяти cuda, мы имеем координаты (x, y) внутри сетки для каждого блока и потока. Я попытался получить доступ к матрицам в примерах ядра в обоих направлениях: порядок строк/столбцов - основной [1]. В первом ядре исправьте меня, если я ошибаюсь, есть доступ к столбцу, а во втором - доступ к строке. Оба ядра инициализируются теми же параметрами, количеством блоков и количеством кадров. Я полагал, что второе ядро, использующее доступ к строкам для основных матриц, будет правильным способом доступа к матрице, как мы были на C++. К сожалению, ядро с порядком столбца-майор возвращает правильные результаты в соответствии с алгоритмом. У кого-нибудь есть хорошее объяснение? Имеют ли эти наблюдения какое-либо отношение к тому факту, что мы называем ядро посредством mexfunction, что означает matlab и, как следствие, доступ к основному порядку столбцов?матрица row/column-major доступ в ядре, называемая mexfunction
Оба ядра называются:
int numElements = rows * cols; // rows and cols of d_A or d_B
int threadsPerBlock = 16;
int blocksPerGrid = ceil((double) (numElements)/threadsPerBlock);
dim3 dimBlock(threadsPerBlock,threadsPerBlock);
dim3 dimGrid(blocksPerGrid, blocksPerGrid);
cudaEuclid<<<dimGrid, dimBlock>>>(d_A, d_B, d_C, rows, cols);
Ядро 1: (рабочая, но не рядные основного C++ стиля)
__global__ void cudaEuclid(float* A, float* B, float* C, int rows, int cols)
{
int i, squareeucldist = 0;
int r = blockDim.x * blockIdx.x + threadIdx.x; // rows
int c = blockDim.y * blockIdx.y + threadIdx.y; // cols
if(r < rows ){
for (i = 0; i < cols; i++)
//column-major order
squareeucldist += (A[r + rows*i] - B[r + rows*i]) * (A[r + rows*i] - B[r + rows*i]);
C[r] = squareeucldist;
squareeucldist = 0;
}
}
ядро 2: (строка-мажорных порядок, с ++ стиль)
__global__ void cudaEuclid(float* A, float* B, float* C, int rows, int cols)
{
int i, squareeucldist = 0;
int c = blockDim.x * blockIdx.x + threadIdx.x; // cols
int r = blockDim.y * blockIdx.y + threadIdx.y; // rows
if(r < rows ){
for (i = 0; i < cols; i++)
//row-major order
squareeucldist += (A[i + cols*r] - B[i + cols*r]) * (A[i + cols*r] - B[i + cols*r]);
C[r] = squareeucldist;
squareeucldist = 0;
}
Вы имеете в виду, что если мы вызываем ядро с помощью основной функции C++ вместо mexfunction, то ядро 2 должно возвращать ожидаемые результаты? – Darkmoor
Это зависит от того, как вы решили организовать данные в своей функции C++. Нет ничего, что помешало бы вам принять макет основного столбца в C++ - это просто не обычный способ хранения матрицы. – chappjc