Openacc против различий openmp и mpi?
Мне было интересно, каковы основные различия между openacc и openmp.
Как насчет MPI, cuda и opencl?
Я понимаю различия между openmp и mpi, особенно часть общей и распределенной памяти
Может ли кто-нибудь из них разрешить установку обработки гибридных gpu-cpu?
Ответы
Ответ 1
OpenMP и OpenACC разрешают параллельное программирование на основе директив.
OpenMP обеспечивает параллельное программирование на вычислительных платформах с общей памятью, например, многоядерные процессоры. Это очень легко использовать, так как достаточно сообщить компилятору некоторые директивы (кодовые аннотации или прагмы) о том, как извлечь parallelism, который запускает синтез параллельной версии исходного исходного кода.
Примером программы 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 Exercise, где вы найдете много других примеров. В этом примере "Hello World" главный поток будет выводить количество задействованных потоков, в то время как каждый поток будет печатать Hello World из потока = xxx.
OpenACC - это набор директив компилятора для указания частей кода C/С++ или Fortran, которые должны быть ускорены приложением ускорителя в качестве графического процессора. Это в значительной степени совпадает с той же философией OpenMP и позволяет создавать высокоуровневые программы ускорения хоста +, без необходимости управления языком программирования ускорителя. Например, OpenACC позволит вам просто ускорить существующие коды 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?.
Директивы OpenACC и OpenMP
Шейн Кук, программирование CUDA, Морган Кауфманн (глава 10)
Благодаря своей природе OpenACC обеспечивает гибридное программирование CPU + GPU. Вы также можете смешивать директивы OpenMP и OpenACC. Например, в 4-GPU-системе вы можете создать 4 тома процессора для разгрузки вычислительной работы на 4 доступных графических процессора. Это описано в книге Шейн Кук. Однако следует упомянуть, что OpenMP 4.0 предусматривает также директивы для работы с разгрузкой подключенных ускорителей, см.
Технический отчет OpenMP 1 о директивах для присоединенных ускорителей
Ответ 2
OpenAcc и OpenMPI разрешают параллельные вычисления на основе директив. OpenMPI пытается использовать преимущества нескольких процессорных ядер, OpenAcc пытается использовать ядра GPU.
MPI - Интерфейс анализа сообщений - это спецификация модели программирования для взаимодействия между node и внутри node в кластере. Процесс MPI-программы имеет частное адресное пространство, которое позволяет программе работать в распределенном пространстве памяти (кластере). Обычно MPI используется в высокопроизводительных вычислениях, где используются протоколы связи с высокой пропускной способностью и низкой задержкой (например, Infiniband и т.д.).
В связи с недавней разработкой параллельных вычислительных технологий, таких как CUDA и OpenMP, MPI добавил в свои спецификации функции, позволяющие использовать параллельные вычисления, предлагаемые ядрами процессора /gpu.
Модели CUDA-Aware-MPI и/или гибридного программирования (MPI + OpenMP) уже используются. Это означает, что программист конечного приложения может писать одну и ту же программу MPI без явной обработки CUDA или OpenMP. Это уменьшило нагрузку на конечного пользователя.
Для Exammple без CUDA_aware-GPU код для MPI_Send a
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);
В библиотеках MPI будут рассмотрены проблемы преобразования буферов памяти хоста в буферы GPU.
Ответ 3
Во-первых, я никогда не программировал использование OpenMP/MPI/OpenAcc/Cuda. Единственный API, который я знаю, это OpenCL, поэтому будьте осторожны с тем, что я говорю ниже, ему нужно подтверждение: p!
Мне больше нравится OpenCL, но я думаю, что в процессе компиляции Cuda и OpenCL нет большой разницы: компилятор включит функции (то есть ядра внутри вашего кода C).
Затем в вашей программе OpenCL/Cuda вы можете выполнять работу процессора между двумя задачами графического процессора.
Для них существует несколько типов памяти:
- global: чтение/запись процессором и gpu
- local: чтение/запись только gpu.
- private: память простого ядра, где хранятся все переменные, объявленные внутри ядра (только gpu-core)
- constant: память, используемая для определения констант (только для gpu-core)
Об этом будет сказано больше, но вы можете легко найти хороших гидов по этому поводу в сети.
Затем, когда их компиляция встроена, вы можете сделать программу GPU/CPU. Вы даже можете использовать OpenMP с OpenCL в одной и той же программе, я не вижу никаких проблем.