Я нашел код о векторном продукте cuda matrix в предыдущей теме: Matrix-vector multiplication in CUDA: benchmarking & performance Сначала я задавался вопросом, почему автор не использовал разделяемую память для dA (матрицы)?Матричный векторный продукт CUDA performance
И почему, почему основной порядок столбцов быстрее, чем порядок строк?
Вот код:
template<typename T>
__global__ void matvec_kernel(const T * __restrict__ dA, const T * __restrict__ dx, T * __restrict__ dy, const unsigned int nRows, const unsigned int nCols)
{
const unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
__shared__ T x_shared[BLOCK_SIZE];
T y_val = 0.0;
#pragma unroll
for (unsigned int m = 0; m < ((nCols + BLOCK_SIZE - 1)/ BLOCK_SIZE); ++m)
{
if ((m * BLOCK_SIZE + threadIdx.x) < nCols) x_shared[threadIdx.x] = dx[threadIdx.x + m * BLOCK_SIZE];
else x_shared[threadIdx.x] = 0.f;
__syncthreads();
#pragma unroll
for (unsigned int e = 0; e < BLOCK_SIZE; ++e) {
// --- Column-major ordering - faster
y_val += dA[tid + (e + BLOCK_SIZE * m) * nRows] * x_shared[e];
// --- Row-major ordering - slower
//y_val += dA[tid * nCols + (e + BLOCK_SIZE * m)] * x_shared[e];
}
__syncthreads();
}
if (tid < nRows) dy[tid] = y_val;
}
Я думаю, на эти два вопроса за 1 день сейчас, и именно поэтому я здесь.
Большое спасибо!
Отличный ответ! Большое спасибо! –
Итак, для достижения максимальной производительности с помощью строки major мне нужно использовать threadIdx.y и nRows вместо threadIdx.x/nCols (во время фазы считывания матрицы)? –
@TitouanParcollet No. Это будет сильно отличаться от указанного ядра. Вышеупомянутый использует один * поток * для каждой строки матрицы, что фактически не является оптимальным с точки зрения производительности, если только матрица не является чрезвычайно большой. Для матрицы строк можно использовать один блок потока * для каждой строки матрицы и использовать параллельное сокращение для вычисления суммы строки. – kangshiyin