Первое Знакомство С Сопроцессором Intel Xeon Phi

Желание познакомиться с сопроцессором Xeon Phi возникло давно, но не было ни возможности, ни времени.

В конце концов произошло чудо и он добрался до объекта желания.

К сожалению, к нам в руки попала не последняя модель – 5110П , но для первого знакомства сойдет. Имея опыт работы с CUDA, меня очень интересовали различия программирования для GPU и сопроцессора.

Второй вопрос был: «Что (кроме дополнительных головных болей) я получу, используя это устройство вместо GPU или CPUЭ» Примечание.

Данная статья не является рекламой или антирекламой какого-либо программного или аппаратного продукта, а лишь описывает личный опыт автора.

Мудрость из краткого руководства разработчика По сути, сопроцессор — это отдельная аппаратная часть, устанавливаемая в слот PCI-e. В отличие от графического процессора, сопроцессор имеет собственную Linux-подобную микроОС, так называемую Card OS или uOS. Есть два варианта запуска кода на Xeon Phi:

  • Скомпилируйте собственный код для архитектуры MIC, используя флаг –mmic.
  • Запускайте код через разгрузку.

    В этом случае часть скомпилированного кода выполняется на хосте (компьютере, содержащем сопроцессор), а часть — на устройстве (в дальнейшем мы будем называть сопроцессор просто устройством).

Еще один важный момент — возможность использовать OpenMP для распределения работы между потоками внутри устройства — отлично, этим мы и займемся.

Сначала реализуем простой алгоритм на ЦП, а потом переделаем программу, чтобы она работала на сопроцессоре.

Описание тестового задания В качестве тестового примера мы выбрали задачу о силовом взаимодействии тел ( проблема с n-телом ): имеется N тел, взаимодействие между которыми описывается неким парным потенциалом, необходимо через некоторое время определить положение каждого тела.

Потенциал и сила парного взаимодействия (в данном случае мы можем взять любую функцию, поскольку физика процесса нас мало интересует):

Первое знакомство с сопроцессором Intel Xeon Phi

Алгоритм прост:

  1. Задаем начальные координаты и скорости тел;
  2. Вычисляем силу, действующую на каждое тело со стороны других;
  3. Определяем новые координаты тел;
  4. Повторяем шаги 2 и 3, пока не добьемся желаемого результата.

Очевидно, что самым «тяжелым» этапом является расчет сил, так как необходимо выполнить около Н 2 операций, причем даже на каждом временном шаге (конечно, используя хитрости вроде списков соседей и помня третий закон Ньютона, можно существенно сократить количество операций, но это уже другая история).

Последовательный код такого алгоритма очень прост и может быть легко преобразован в параллельный код с помощью директив OpenMP. Параллельный код с использованием OpenMP

   

/*---------------------------------------------------------*/ /* N-Body simulation benchmark */ /* written by M.S.Ozhgibesov */ /* 04 July 2015 */ /*---------------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <time.h> #include <omp.h> #define HOSTLEN 50 int numProc; // Initial conditions void initCoord(float *rA, float *vA, float *fA, \ float initDist, int nBod, int nI); // Forces acting on each body void forces(float *rA, float *fA, int nBod); // Calculate velocities and update coordinates void integration(float *rA, float *vA, float *fA, int nBod); int main(int argc, const char * argv[]) { int const nI = 32; // Number of bodies in X, Y and Z directions int const nBod = nI*nI*nI; // Total Number of bodies int const maxIter = 20; // Total number of iterations (time steps) float const initDist = 1.0; // Initial distance between the bodies float *rA; // Coordinates float *vA; // Velocities float *fA; // Forces int iter; double startTime0, endTime0; char host[HOSTLEN]; rA = (float*)malloc(3*nBod*sizeof(float)); fA = (float*)malloc(3*nBod*sizeof(float)); vA = (float*)malloc(3*nBod*sizeof(float)); gethostname(host, HOSTLEN); printf("Host name: %s\n", host); numProc = omp_get_num_procs(); printf("Available number of processors: %d\n", numProc); // Setup initial conditions initCoord(rA, vA, fA, initDist, nBod, nI); startTime0 = omp_get_wtime(); // Main loop for ( iter = 0; iter < maxIter; iter++ ) { forces(rA, fA, nBod); integration(rA, vA, fA, nBod); } endTime0 = omp_get_wtime(); printf("\nTotal time = .

4f [sec]\n", endTime0 - startTime0); free(rA); free(vA); free(fA);

Теги: #компилятор Intel #xeon phi #openmp #Параллельное программирование
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.