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 в одной и той же программе, я не вижу никаких проблем.