Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 02.06.2014 | Доступ: свободный | Студентов: 183 / 28 | Длительность: 04:58:00

Лекция 1: Элементы оптимизации прикладных программ для Intel Xeon Phi: Intel MKL, Intel VTune Amplifier XE

Лекция 1: 12345 || Лекция 2 >

Compiler Assisted Offload (CAO)

В данной модели процесс offload’а явно контролируется программистом с помощью директив компилятора. По сути, данная модель является обычной offload моделью программирования ускорителя, а значит, позволяет пользоваться всеми возможностями компилятора для переноса части вычислений на сопроцессор. Подробности о программировании в режиме offload можно найти в лекции №5 курса "Введение в принципы функционирования и применения современных мультиядерных архитектур (на примере Intel Xeon Phi)".

Рассмотрим пример вызова функции для умножения матриц:

#pragma offload target(mic) \
in(transa, transb, N, alpha, beta) \
in(A:length(matrix_elements)) \
in(B:length(matrix_elements)) \
in(C:length(matrix_elements)) \
out(C:length(matrix_elements) alloc_if(0))
{
    sgemm(&transa, &transb, &N, &N, &N, &alpha, A, &N, B,
        &N, &beta, C, &N);
}

В данном случае явно указан код (функция умножения матриц), который переносится на сопроцессор, а также описаны все действия по управлению передачей данных.

В отличие от режима AO, где на Intel Xeon Phi может работать только некоторое подмножество функций Intel MKL, текущая модель позволяет запускать на сопроцессоре абсолютно все функции библиотеки. Однако это не означает, что во всех случаях удастся получить лучшую производительность, чем при работе только на CPU.

Модель CAO позволяет использовать все offload возможности компилятора для достижения лучшей производительности, в частности оптимизировать работу с данными на сопроцессоре, явно указывая моменты выделения/удаления памяти. Это позволяет, например, организовать переиспользование данных на сопроцессоре и тем самым обеспечить снижение объема передаваемой на хост (или с хоста) информации:

__declspec(target(mic)) static float *A, *B, *C, *C1;

// Transfer matrices A, B, and C to coprocessor and do not
// de-allocate matrices A and B
#pragma offload target(mic) \
in(transa, transb, M, N, K, alpha, beta, LDA, LDB, LDC) \
in(A:length(NCOLA * LDA) free_if(0))\
in(B:length(NCOLB * LDB) free_if(0)) \
inout(C:length(N * LDC))
{
    sgemm(&transa, &transb, &M, &N, &K, &alpha, A, &LDA,
        B, &LDB, &beta, C, &LDC);
}

// Transfer matrix C1 to coprocessor and reuse
// matrices A and B
#pragma offload target(mic) \
in(transa1, transb1, M, N, K, alpha1, \
beta1, LDA, LDB, LDC1) \
nocopy(A:length(NCOLA * LDA) alloc_if(0) free_if(0)) \
nocopy(B:length(NCOLB * LDB) alloc_if(0) free_if(0)) \
inout(C1:length(N * LDC1))
{
    sgemm(&transa1, &transb1, &M, &N, &K, &alpha1,
        A, &LDA, B, &LDB, &beta1, C1, &LDC1);
}

// Deallocate A and B on the coprocessor
#pragma offload target(mic) \
nocopy(A:length(NCOLA * LDA) free_if(1)) \
nocopy(B:length(NCOLB * LDB) free_if(1)) \
{ }

Явное управление запуском кода на ускорителе позволяет также делать перекрытие вычислений с обменом данными, либо обеспечивать одновременную работу CPU и ускорителя. Однако возможности автоматической балансировки нагрузки теряются.

При использовании модели CAO прежде всего следует избегать ненужных обменов данными между хостом и сопроцессором (по аналогии с приведенным выше примером). Также как и для AO, следует освободить ядро операционной системы ускорителя от вычислений. И наконец, имеет смысл работать с увеличенным до 2 МБ размером страницы памяти. Для этого следует использовать переменную окружения, инициализированную как:

MIC_USE_2MB_BUFFERS=64K

При этом будут использоваться страницы размером в 2 МБ (64 КБ для данной переменной является пороговым значением, начиная с которого размер страниц памяти будет увеличен до 2 МБ).

Заметим также, что в рамках одной программы возможно использование обеих этих моделей. Одни вызовы можно делать в режиме AO, другие в режиме CAO. Единственное ограничение здесь состоит в необходимости явно указывать распределение нагрузки для AO вызовов, иначе все они будут использовать только CPU.

Лекция 1: 12345 || Лекция 2 >