Обзор новых возможностей OpenMP — —стандарта для распараллеливания программ на языках Си, Си++ и Фортран Алексей Батаев Intel Содержание 1. Что такое OpenMP*? 2. Цели OpenMP* 3. История OpenMP* 4. Потоковый параллелизм 5. Детали OpenMP 4.0 2 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Что такое OpenMP*? http://www.openmp.org/ Открытый стандарт для распараллеливания программ на языках С, С++ и Фортран Определяет набор директив компилятора, библиотечных функций/процедур и переменных среды окружения для создани многопоточных программ Очень важен в области High Performance Computing (HPC) Требует поддержки со стороны компилятора 3 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Цели OpenMP* Стандартизация Единый стандарт для различных систем/архитектур/ платформ с общей памятью Определен совместными усилиями ведущих поставщиков программного и аппаратного обеспечения Краткость и выразительность Небольшой набор директив и дополнительных элементов (clause) Простота использования Упрощенный механизм создания параллельных программ, практически не влияющий на работу программиста Переносимость Поддерживается в С/С++ и Фортран Поддерживается но множестве платформ (Unix*/Linux*, MacOS*, Windows*) 4 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. История OpenMP* Расширения к Фортрану Начало 90-х Проект Х3Н5 – первая попытка стандарта ANSI 1994 год Начало разработки OpenMP 1997 год Поддерживается OpenMP Architecture Review Board (ARB) Intel, AMD*, ARM*, Cray*, IBM*, HP*, Micron*, NEC*, Nvidia*, Oracle* etc. 5 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. История OpenMP* Версии 1.0-2.5 (Октябрь 1997 – Май 2005) Первые версии, внедрение и развитие потокового распараллеливания циклов Версии 3.0, 3.1 (Май 2008 – Июль 2011) Добавление и развитие поддержки независимых задач Версия 4.0 … (Июль 2013) Поддержка векторизации циклов (SIMD), поддержка ускорителей (target), зависимые задачи, встроенные механизмы обработки ошибок (cancel), пользовательские редукции, расширение атомарных конструкций 6 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Модель с разделяемой памятью Все потоки имеют доступ к глобальной общей памяти Данные могут быть общие и приватные Общие данные доступны всем потокам Приватные данные доступны только одному потокувладельцу Требуется синхронизация для доступа к общим данным 7 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Структура OpenMP*-программы Программа представляется в виде последовательных участков кода (serial code) и параллельных регионов (parallel region) Каждый поток имеет номер Thread Id Мастер поток (master) имеет номер 0 Память процесса (heap) является общей для всех потоков OpenMP реализует динамическое управление потоками (task parallelism) 8 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Пример OpenMP*-программы #include <omp.h> int main() { #pragma omp parallel { printf("Thread %d\n", omp_get_thread_num()); } return 0; } 9 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Компиляция OpenMP* -программы $ clang –fopenmp –o prog ./prog.c $ ./prog Thread 0 Thread 1 Thread 3 Thread 2 $ export OMP_NUM_THREADS=2 $ ./prog Thread 0 Thread 1 По умолчанию количество потоков = количеству логических процессоров в системе 10 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Модель выполнения OpenMP* Мастер поток #pragma omp parallel Параллельные потоки (team) Неявная синхронизация Мастер поток 11 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Что нового в OpenMP* 4.0? Поддержка ускорителей (offloading) Векторизация циклов (SIMD loops) Привязка потоков к ядрам процессора Группы задач и зависимые задачи Обработка ошибок Пользовательские редукции Расширение атомарных конструкций Поддержка Fortran 2003 12 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Поддержка ускорителей (offloading) Код и данные выгружаются на ускоритель Директива target создает задачи, которые должны быть выполнены на ускорителе Поддерживается множество всевозможных ускорителей: GPU MIC (Many Integrated Core) DSP (Digital Signal Processing) FPGA (Field-Programmable Gate Array) Основная память Target Данные Данные Задача Задача #pragma omp target … { … } 13 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Пример 14 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Новые директивы для поддержки ускорителей target data - отображение областей памяти программы в память ускорителя teams - организация групп потоков на ускорителях distribute - разбиение циклов для распараллеливания на ускорителях declare target - пометка данных для использования только на ускорителях target update – синхронизация данных между хостом и ускорителем 15 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. OpenMP*: Уровни параллелизации Потоки – #pragma omp parallel for Сопроцессоры/Ускорители – #pragma omp target SIMD – #pragma omp simd 16 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. SIMD: Что это? Core Instruction Input Output Как выполнять код быстрее? Core Core Исполнять инструкции в несколько потоков Core – #pragma omp parallel for Still 1 instruction Vector width Core Обрабатывать несколько блоков данных за одну инструкцию Vector width evolution 512 – SIMD, Single Instruction Multiple Data, векторные инструкции – #pragma omp simd 64 MMX Core 128 SSE 256 AVX AVX-512 Core Оба подхода – #pragma omp parallel for simd Core 17 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. • Форсирует получение максимальной скорости • Переносимость • Масштабируемость • Нет затрат на оптимизацию • Предсказуемая производительность • • • • Макимальная производительность Низкая переносимость Высокая стоимость разработки Низкая расширяемость Auto Переносимость Масштабируемость Нет затрат на оптимизацию Неизвестная производительность Explicit • • • • … float *A, *B, *C; ... #pragma omp simd for(int i…) C[i] = A[i] + B[i]; $> clang –O2 –Xclang – fopenmp=… Manual SIMD: Как? … float *A, *B, *C; ... for(int i…) C[i] = A[i] + B[i]; $> clang –O2 … #include "xmmintrin.h“ … float *A, *B, *C; __m128 a, b, c; ... for(int i…) { a = _mm_load_ps(A + i*4); b = _mm_load_ps(B + i*4); c = _mm_add_ps(a, b); _mm_store_ps(C+i * 4, c); } $> clang … 18 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. SIMD: Автовекторизация - Прагмы Автовекторизация не работает, если: Эвристика говорит "нет" сложные зависимости по данным цикл вложен в другой цикл // RT pointer aliasing checks: float* void doThings(float *a, float *b, float *c, float *d, float *e, unsigned N, unsigned K) { for(int i = 0; i < N; ++i) // not innermost for(int j = 0; j < N; ++j) // non-trivial data-deps due to unknown K a[i + j] = b[i + K] + c[i + K] + d[i + K] + e[i + K]; } OpenMP* SIMD прагмы: не выполнять никакого анализа и векторизовать! // the only change #pragma omp simd collapse(2) for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) a[i + j] = … … $> clang -mllvm -debug-only=loop-vectorize … LV: Checking a loop in "doThings" from test.c:4:3 ... LV: Found a runtime check ptr: %arrayidx18.us = … LV: We need to do 4 pointer comparisons LV: We can't vectorize because we can't find the array bounds LV: Can't vectorize due to memory conflicts $> clang -mllvm -debug-only=loop-vectorize –Xclang –fopenmp=… LV: Checking a loop in "doThings" from test.c:4:3 LV: Loop hints: force=enabled width=0 unroll=0 LV: A loop annotated parallel, ignore memory dependency checks. LV: We can vectorize this loop! 19 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Привязка потоков к ядрам процессора Переменная окружения OMP_PLACES определяет логику привязки потоков к ядрам процессора Добавлена clause proc_bind(), позволяющая прагме "omp parallel" привязать потоки к ядрам процессора 20 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Зависимость между задачами Для директивы "omp task" добавлена clause depend( [in|out|inout] : <list of expressions> ) #include <stdio.h> int main() { int x = 1; #pragma omp parallel #pragma omp single { #pragma omp task shared(x) depend(out: x) x = 2; #pragma omp task shared(x) depend(in: x) printf("x + 1 = %d. ", x+1); #pragma omp task shared(x) depend(in: x) printf("x + 2 = %d\n", x+2); } return 0; } 21 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Обработка ошибок Добавлены директивы "omp cancel" и "omp cancellation point" void example() { std::exception *ex = NULL; #pragma omp parallel shared(ex) { #pragma omp for for (int i = 0; i < N; i++) { try { causes_an_exception(); } catch (const std::exception *e) { #pragma omp atomic write ex = e; #pragma omp cancel for } } // if an exception has been raised, cancel parallel region if (ex) { #pragma omp cancel parallel } } } 22 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Пользовательские редукции Добавлена директива "omp declare reduction", позволяющая задавать пользовательские редукции #pragma omp declare reduction (+ : int, float : omp_out *= omp_in) void foo(int &ivar, float &fvar, double &dvar, int **argv, int n, int m) { #pragma omp parallel for reduction(+: ivar, fvar, dvar) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) { ivar += argv[i][j]; fvar += argv[i][j]; dvar += argv[i][j]; } } 23 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Поддержка в компиляторах OpenMP 3.0 Intel Fortran and C/C++ versions 11.0 and 11.1 compilers. GCC* 4.3.1 IBM* XL C/C++ compiler Sun* Studio 12 update 1 OpenMP 3.1 Intel Fortran and C/C++ compilers 12.1 GCC 4.7 Clang* 3.7 + частично 4.0 OpenMP 4.0 Intel Fortran and C/C++ compilers 15.0 GCC 4.9.0 for C/C++, GCC 4.9.1 for Fortran 24 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Вопросы? Обзор новых возможностей OpenMP —стандарта для распараллеливания программ на языках Си, Си++ и Фортран Алексей Батаев 25 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Legal Disclaimer & Optimization Notice INFORMATION IN THIS DOCUMENT IS PROVIDED “AS IS”. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO THIS INFORMATION INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT. Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark and MobileMark, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products. Copyright © 2014, Intel Corporation. All rights reserved. Intel, Pentium, Xeon, Xeon Phi, Core, VTune, Cilk, and the Intel logo are trademarks of Intel Corporation in the U.S. and other countries. Optimization Notice Intel’s compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice. Notice revision #20110804 26 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. Backup 28 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. OpenMP* Coprocessor/Accelerator Support Library Required for support of OpenMP 4.0 target constructs Under development by Intel, IBM*, TI*, etc. in clang-omp repository Plan to support x86, x86-64, PowerPC* and ARM* as hosts , multiple targets (Intel® Xeon Phi™ coprocessor, GPUs, FPGAs, …) Phi code LLVM generatedGPU code host code Data Fat binary Phi offload RTL Phi GPU offload RTL GPU libomptarget.so HOST 29 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. OpenMP* SIMD: Status in Clang OpenMP SIMD requires support from both frontend and backend Frontend parses OpenMP SIMD pragmas and creates LLVM IR metadata hints, which are then used by vectorizer #pragma omp simd safelen(4) for(int i = 0; i < N; ++i) … LV: Checking a loop in … LV: Loop hints: force=enabled width=4 unroll=0 … !42 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true} !43 = metadata !{metadata !"llvm.loop.vectorize.width", i32 4} In case of collapse clause frontend creates a new loop, collapsing the existing loop nest into single loop 30 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. OpenMP Constructs Representation #pragma omp parallel if (<condition>) <body> Stmt OMPClause OMPExecutableDirective OMPClause OMPParallelDirective … CapturedStmt (with <body>) OMPClause OMPIfClause <condition> Expr 31 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others. OpenMP Constructs Representation: Continued OMPIFClause <condition> Expr CapturedStmt <body> Stmt OMPParallelDirective br i1 <condition>, label %omp.if.then, label%omp.if.else omp.if.else: <body> br label %omp.if.end omp.if.then: %3 = bitcast %struct.anon* %agg.captured to i8* call void @__kmpc_fork_call(<loc>, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8*)* @.omp_microtask. to void (i32*, i32*, ...)*), i8* <captured_vars>) br label %omp.if.end omp.if.end: … define internal void @.omp_microtask.(i32*, i32*, i8*) #0 { %.gtid. = load i32* %0 <body> call i32 @__kmpc_cancel_barrier(<loc>, i32 %.gtid.) } 32 Optimization Notice Copyright © 2014, Intel Corporation. All rights reserved. *Other names and brands may be claimed as the property of others.