WedX - журнал о программировании и компьютерных науках

Паралелизация OpenMP препятствует векторизации

Я новичок в OpenMP, и я пытаюсь парализовать следующий код с помощью OpenMP:

#pragma omp parallel for
for(int k=0;k<m;k++)
{
   for(int j=n-1;j>=0;j--)
   {
       outX[k+j*m] = inB2[j+n * k] / inA2[j*n + j];

       for(int i=0;i<j;i++)
       {
           inB2[k*n+i] -= inA2[i+n * j] * outX[k + m*j];
       }
   }
}

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

#pragma omp parallel for
for(int i=0;i<j;i++)
{
    inB2[k*n+i] -= inA2[i+n * j] * outX[k + m*j];
}

компилятор не векторизует внутренний цикл («версия цикла для векторизации из-за возможного сглаживания»), что замедляет его работу. Я скомпилировал его с помощью gcc -ffast-math -std=c++11 -fopenmp -O3 -msse2 -funroll-loops -g -fopt-info-vec prog.cpp

Спасибо за любой совет!

РЕДАКТИРОВАТЬ: я использую ключевое слово __restrict для массивов.

EDIT2: Интересно то, что когда я сохраняю только прагму во внутреннем цикле и удаляю ее из внешнего, gcc векторизует ее. Так что проблема возникает только тогда, когда я пытаюсь парализовать оба цикла.

EDIT3: компилятор векторизует цикл, когда я использую #pragma omp parallel для simd. Но это все равно медленнее, чем без распараллеливания внутреннего цикла.

16.11.2016

  • Векторизовать вручную легче, чем распараллеливать. Почему бы просто не сделать это? (и сохранить автоматическое распараллеливание) 16.11.2016

Ответы:


1

Я предполагаю, что после того, как вы распараллелили внутренний цикл, ваш компилятор потерял отслеживание inA2, inB2 и outX. По умолчанию предполагается, что любые области памяти, на которые указывают любые указатели, могут перекрываться друг с другом. В языке C стандарт C99 ввел ключевое слово restrict, которое сообщает компилятору, что указатель указывает на блок памяти, на который не указывает какой-либо другой указатель. В C ++ такого ключевого слова нет, но, к счастью, у g++ есть соответствующее расширение. Поэтому попробуйте добавить __restrict к объявлениям указателей, затронутых циклом. Например, заменить

double* outX;

с участием

double* __restrict outX;
16.11.2016
  • К сожалению, это не так. Я использую __restrict. Хороший момент, я добавлю его в OP. 16.11.2016

  • 2

    Вы пробовали сначала сделать внутренний контур векторным? а затем добавление параллельной части (что может привести к снижению производительности в зависимости от промахов кеша)

    #pragma omp parallel for
    for(int k=0;k<m;k++)
    {
       for(int j=n-1;j>=0;j--)
       {
           outX[k+j*m] = inB2[j+n * k] / inA2[j*n + j];
    Q1 = k*n
    Q2 = n*j
    Q3 = m*j + k
    #pragma omp declare simd private(i,j,k,m,Q1,Q2,Q3) linear(i) uniform(outX,inA2,inB2) shared(inB2,inA2,outX)
           for(int i=0;i<j;i++)
           {
               inB2[Q1+i] -= inA2[Q2+i] * outX[Q3];
           }
       }
    }
    

    Мне всегда требуется некоторое время, чтобы правильно настроить #pragma с общими, общедоступными и т. Д. И я не тестировал это.

    19.11.2016
  • Спасибо за идею. Как я уже упоминал в EDIT3, я решил его векторизовать, просто используя #pragma omp parallel for simd. Но это все равно медленнее, чем без парализации внутреннего цикла. 19.11.2016
  • Это может указывать на то, что это ограниченная полоса пропускания, а не вычислительная. 20.11.2016

  • 3

    Спасибо всем за ответы. Мне удалось векторизовать внутренний цикл с помощью #pragma omp parallel for simd, но программа работала медленнее, чем без распараллеливания. В конце концов я нашел немного другой алгоритм решения проблемы, который работает намного быстрее. Спасибо за помощь ребята!

    19.11.2016
  • Обычно лучше всего подходит VIPO (Vectorize Inner, Parallel Outer). Таким образом, чистый SIMD во внутреннем цикле (без «параллельности для»), а затем, помогает ли распараллеливание внешнего цикла, обычно является попыткой проверить это и увидеть. В ситуациях с ограниченной пропускной способностью иногда помогает предварительная выборка, но промахи кеша могут привести к тому, что многие ядра будут выполнять небольшую реальную работу, тогда как одно ядро ​​может беспрепятственно передавать данные. Редко бывает легко угадать. 20.11.2016
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]