Опубликован: 30.05.2014 | Уровень: для всех | Доступ: платный | ВУЗ: Нижегородский государственный университет им. Н.И.Лобачевского

Лекция 5: Элементы оптимизации прикладных программ для Intel Xeon Phi. Intel C/C++ Compiler

Векторизация внешних циклов

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

Векторизация внешнего цикла может быть выполнена одним из перечисленных ниже способов:

  1. Посредством добавления директивы #pragma simd перед внешним циклом.
  2. С помощью директивы #pragma simd и элементарных функций.
  3. С использованием технологии Array Notation [5.9].

Рассмотрим следующий пример [5.10]:

for(LocalOrdinalType row=ib*BLOCKSIZE; row<top; ++row) {
    local_y[row]=0.0;

    for(LocalOrdinalType i=Arowoffsets[row];
            i<Arowoffsets[row+1]; ++i) {
        local_y[row] += Acoefs[i]*local_x[Acols[i]];
    }
}

Выполним векторизацию данного кода вторым из перечисленных выше способов:

#pragma simd
for(LocalOrdinalType row=ib*BLOCKSIZE; row<top; ++row) {
    local_y[row]=0.0;
    Inner_loop_elem_function(local_y, row, Acoefs, local_x,
        Acols, Arowoffsets);
}

__declspec(vector(uniform(Arowoffsets, Acoefs, local_x,
        Acols, local_y), linear(row))))
    Inner_loop_elem_function(float *local_y, int row, 
        float *Acoefs, float *local_x, int *Acols,
        int *Arowoffsets)
{
    for(LocalOrdinalType i=Arowoffsets[row];
            i<Arowoffsets[row+1]; ++i) {
        local_y[row] += Acoefs[i]*local_x[Acols[i]];
    }
}

Идея векторизации здесь следующая. Во-первых, описываем внутренний цикл как тело элементарной функции. Во-вторых, помещаем вызов полученной функции в тело внешнего цикла. И в-третьих, применяем simd директиву для векторизации внешнего цикла.

Подробнее о способах векторизации внешних циклов можно узнать по ссылкам [5.9,5.10].

Svetlana Svetlana
Svetlana Svetlana

Здравствуйие! Я хочу пройти курс Введение в принципы функционирования и применения современных мультиядерных архитектур (на примере Intel Xeon Phi), в презентации самостоятельной работы №1 указаны логин и пароль для доступ на кластер и выполнения самостоятельных работ, но войти по такой паре логин-пароль не получается. Как предполагается выполнение самосоятельных работ в этом курсе?

Егор Кузьмин
Егор Кузьмин
Россия, г. Москва
Вера Борисова
Вера Борисова
Россия