Здравствуйие! Я хочу пройти курс Введение в принципы функционирования и применения современных мультиядерных архитектур (на примере Intel Xeon Phi), в презентации самостоятельной работы №1 указаны логин и пароль для доступ на кластер и выполнения самостоятельных работ, но войти по такой паре логин-пароль не получается. Как предполагается выполнение самосоятельных работ в этом курсе? |
Лекция 3: Выполнение программ на Intel Xeon Phi. Модели организации вычислений с использованием Intel Xeon Phi
Создание приложений для Intel Xeon Phi
Разработка приложений для архитектуры Intel Xeon Phi требует наличия тех же знаний и навыков, что и разработка параллельных приложений для распределенных многоядерных систем. Можно использовать следующие программные инструменты:
- средства разработки "Intel Parallel Studio XE 2013", "Intel Cluster Studio XE 2013", "Intel(R) SDK for OpenCL Applications XE 2013 Beta", gcc (в настоящий момент не поддерживает векторные инструкции) и др.;
- библиотеки Intel Math Kernel Library (Intel MKL), Intel Threading Building Blocks (Intel TBB), Intel Integrated Performance Primitive (Intel IPP), входящие в состав средств разработки Intel, а также Intel MPI for Linux, MPICH2, Boost и др.
- отладчики (Intel Debugger, gdb, totalview), профилировщики (входят в состав средств разработки Intel), средства виртуализации (xen) и т.д.
Компиляция гетерогенных приложений производится в базовой системе. В случае использования режима Offload, для всех offload-блоков создается две версии кода – для базовой системы и для сопроцессора. Компилятор создает исполняемые файлы и/или библиотеки, содержащие весь код для процессора и сопроцессора. Во время исполнения программы при первом вызове offload-кода проверяется наличие сопроцессора Intel Xeon Phi. В случае его наличия и незанятости происходит загрузка на него двоичного исполняемого файла и инициализация необходимых библиотек, после чего выполняется вызов offload-кода. В случае отсутствия сопроцессора происходит вызов версии функции для базовой системы. Таким образом, приложение будет работать как при наличии сопроцессора, так и при его отсутствии.
Рассмотрим несколько версий программы сложения элементов массива для различных моделей выполнения.
Программы для режима выполнения Offload
При использовании режима Offload порядок использования сопроцессора определяется посредством директив компилятора – pragma в языках C/C++, директив в FORTRAN.
Последовательное синхронное выполнение
Блок программы, который следует выполнить на сопроцессоре, указывается посредством директивы #pragma offload target(mic). Операторы in, out, inout определяют необходимость и направление передачи данных между памятью хоста и сопроцессора. По умолчанию все переменные, объявленные вне offload-блока, перед началом его выполнения копируются на сопроцессор, а по окончании выполнения копируются назад в память базовой системы.
float Sum(float *Data, int Size){ float Ret = 0.0f; #pragma offload target(mic) in(Data:length(Size)) for (int i = 0; i < Size; i ++){ Ret += Data[i]; } return Ret; }
В данном примере переменная Ret перед началом выполнения offload-кода будет скопирована из памяти хост-системы в память сопроцессора, а по окончании – назад из памяти сопроцессора в основную память системы.
Offload-код данной версии будет выполняться последовательно на одном ядре сопроцессора.
Последовательное синхронное выполнение с векторизацией
Компилятор Intel по умолчанию выполняет векторизацию кода. Можно облегчить ему задачу, используя операции с массивами в формате Intel Cilk Plus Extended Array Notation.
float Sum(float *Data, int Size){ float Ret = 0.0f; #pragma offload target(mic) in(Data:length(Size)) //Intel Cilk Plus Extended Array Notation Ret = __sec_reduce_add(Data[0:Size]); return Ret; }
Offload-код данной версии будет выполняться последовательно на одном ядре сопроцессора с использованием векторных вычислений, выполняя по 16 операций сложения за одну операцию.
Последовательное асинхронное выполнение
При использовании режима Offload можно использовать технику двойной буферизации, обеспечивающую одновременное выполнение offload-функции и передачу на сопроцессор входных данных для следующего вызова и/или передачу выходных данных в память основной системы для предыдущего вызова (подробнее см. [2]). Пример программы, использующей двойную буферизацию, имеется в составе средств разработки Intel (…/C++/mic_samples/intro_sampleC/sampleC13.c)
Явное копирование памяти
Для передачи между хостом и сопроцессором сложных структур данных, например, использующих указатели, в языках C/C++ реализована модель "разделяемой памяти". Она обеспечивает размещение специальным образом маркированных переменных (квалификатор типа _Cilk_shared) по одним и тем же виртуальным адресам на хост-системе и сопроцессоре, а также включает специальные функции для динамического выделения памяти по одним и тем же адресам на хост-системе и сопроцессоре.
"Разделяемая память" не может быть реализована непосредственным отображением адресов памяти сопроцессора на адреса памяти хост-системы, эти подсистемы памяти являются полностью независимыми. Этот механизм является вариацией обычного вызова offload-кода – при выполнении вызова функции с использованием квалификатора _Cilk_offload определяется, какие изменения произошли в копии, хранящейся в памяти хост-системы, и изменения передаются в память сопроцессора (аналогично при возврате из функции).
float * _Cilk_shared Data; _Cilk_shared float MIC_Sum(int Size) { float Result; for (int i = 0; i < Size; i++){ Result += Data[i]; } return Result; } int main(){ size_t Size = 1000000; int MemSize; MemSize = Size * sizeof(float); Data = (_Cilk_shared float *) _Offload_shared_malloc (MemSize); for (int i = 0; i < Size; i++){ Data[i] = i; } _Cilk_offload MIC_Sum(Size); _Offload_shared_free(Data); return 0; }
Offload-код данной версии будет выполняться последовательно на одном ядре сопроцессора.
Параллельное программирование для сопроцессора Intel Xeon Phi
Большинство возможностей, доступных для хост-системы, реализованы и для Intel Xeon Phi. Вы можете использовать:
- Intel Threading Building Blocks (Intel® TBB)
- OpenMP*
- Intel® Cilk Plus
- pthreads*
- MPI
Необходимо помнить, что потоки программ, выполняющихся на хост-системе и на сопроцессоре, являются совершенно независимыми, и можно использовать, например, OpenMP только в части программы, выполняющейся на хосте, или только в части, выполняющейся на сопроцессоре, или в обоих частях сразу.
Использование MPI не отличается от разработки программ для кластеров, состоящих из многоядерных узлов, за исключением необходимости распределения нагрузки при использовании симметричной модели выполнения.