openacc против openmp & mpi различия?
Мне было интересно, каковы основные различия между openacc и OpenMP. Как насчет MPI, cuda и opencl ? Я понимаю различия между openmp и mpi, особенно часть об общей и распределенной памяти Любой из них допускает гибридную настройку обработки gpu-cpu ?
4 ответов
OpenMP и OpenACC включают директивное параллельное программирование.
OpenMP включает параллельное программирование на платформах с общей памятью, например, многоядерных процессорах. Он очень прост в использовании, так как достаточно сообщить компилятору некоторые директивы (аннотации кода или прагмы) о том, как извлечь параллелизм, который запускает синтез параллельной версии входного исходного кода.
примером программы OpenMP "Hello World" с прагмами является следующее
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(nthreads, tid)
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} /* All threads join master thread and disband */
}
источником вышеуказанного кода является OpenMP Упражнение откуда вы найдете много других примеров. В этом примере "Hello World" главный поток выведет количество задействованных потоков, в то время как каждый поток будет печатать Привет мир из потока = xxx.
OpenACC-это набор директив компилятора для указания частей кода C/C++ или Fortran, которые должны быть ускорены присоединенным ускорителем, как GPU. Следует в значительной степени та же философия OpenMP и позволяет создавать высокоуровневые программы host+accelerator, опять же без необходимости управления языком программирования accelerator. Например, OpenACC позволит вам просто ускорить существующие коды C / C++ без необходимости изучать CUDA (с некоторым штрафом за производительность, конечно).
типичный код OpenACC будет выглядеть следующим образом
#pragma acc kernels loop gang(32), vector(16)
for (int j=1; j<n-1; j++)
{
#pragma acc loop gang(16), vector(32)
for (int i=1; i<m-1; i++)
{
Anew[j][i] = 0.25f * (A[j][i+1] + A[j-1][i]);
...
}
}
выше исходный код взят из блога Пример OpenACC (Часть 1), где вы можете найти более полезный материал, чтобы понять разницу между OpenMP и OpenACC.
другие источники следующие
как API OpenACC относится к API OpenMP?.
Шейн Кук, Программирование CUDA, Морган Кауфманн (Глава 10)
из-за самой своей природы OpenACC включает гибридное Программирование CPU+GPU. Вы также можете смешать Директивы OpenMP и OpenACC. Например, в системе 4-GPU можно создать 4 потока ЦП для разгрузки вычислительной работы до 4 доступных графических процессоров. Это описано в книге Шейна Кука. Однако следует отметить, что OpenMP 4.0 также предусматривает директивы для разгрузки работы присоединенных ускорителей, см.
технический отчет OpenMP 1 о директивах для присоединенных ускорителей
OpenAcc и OpenMPI включают параллельные вычисления на основе директив. OpenMPI пытается воспользоваться несколькими ядрами процессора, OpenAcc пытается использовать ядра GPU.
MPI -- Message parsing Interface-это спецификация модели программирования для межузловой и внутриузловой связи в кластере. Процесс MPI-программы имеет индивидуальный адрес, что позволяет программе работать на распределенной памяти (кластера). Обычно MPI используется в высокопроизводительных вычислениях где протоколы связи с высокой пропускной способностью и низкой задержкой (например, Infiniband и т. д.. ) не использовать.
с недавней разработкой параллельных вычислительных технологий, таких как CUDA и OpenMP, MPI добавил функции в свою спецификацию, чтобы воспользоваться параллельными вычислениями, предлагаемыми ядрами cpu/gpu.
CUDA-Aware-MPI и / или гибридные модели программирования ( MPI + OpenMP) уже используются. Это означает, что end application programmer может написать ту же программу MPI без явной обработки CUDA или OpenMP. Это уменьшило нагрузку на конечного пользователя.
для примера без CUDA_AWARE-GPU, код для MPI_Send an d MPI_Recv будет как
//MPI rank 0
cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);
MPI_Send(s_buf_h,size,MPI_CHAR,1,100,MPI_COMM_WORLD);
//MPI rank 1
MPI_Recv(r_buf_h,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);
cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);
но с CUDA_awre_MPI
//MPI rank 0
MPI_Send(s_buf_d,size,MPI_CHAR,1,100,MPI_COMM_WORLD);
//MPI rank n-1
MPI_Recv(r_buf_d,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);
в libararies MPI будет адрес проблемы преобразования буферов основной памяти в буферы ГПУ.
читайте об общих и распределенных парадигмах, на ваш вопрос можно ответить на двух курсах уровня grad более подробно, Я рекомендую посещать летнее обучение TACC (Texas Advanced Computing Center), если вы действительно заинтересованы в руки на обучение
во-первых, я никогда не программировал с помощью OpenMP/MPI/OpenAcc / Cuda. Единственный API, который я знаю, - OpenCL, поэтому будьте осторожны с тем, что я говорю ниже, ему нужно подтверждение :p !
Мне более комфортно с OpenCL, но я думаю, что нет большой разницы между Cuda и OpenCL в их процессе компиляции : компилятор встроит функции (т. е. ядра внутри вашего кода C). Затем в вашей программе OpenCL / Cuda вы можете выполнять работу процессора между двумя задачами GPU.
для них, существует несколько типов памяти :
- global: чтение / запись процессором и gpu
- local: чтение / запись только gpu.
- private: память простого ядра, где хранятся все переменные, объявленные внутри ядра (только gpu-core)
- константа: память, используемая для определения констант (только gpu-core)
было бы больше сказать об этом, но вы можете легко найти хорошие руководства об этом на сеть.
затем, поскольку их компиляция встроена, вы можете сделать программу GPU / CPU. Вы даже можете использовать OpenMP с OpenCL в той же программе, я не вижу никаких проблем.