Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property.

Similar presentations


Presentation on theme: "Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property."— Presentation transcript:

1 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Оптимизирующий компилятор. Векторизация.

2 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Тенденция в развитии микропроцессоров: Последовательное выполнение инструкций Параллельное выполнение инструкций  Конвейеризация  Суперскалярность  Векторные операции  Многоядерные и многопроцесорные решения Оптимизирующий компилятор – инструмент, транслирующий исходный код программы в исполняемый модуль и оптимизирующий исходный код для получения лучшей производительности. Параллелизация – трансформация последовательно выполняющейся программы в программу, в которой наборы инструкций выполняются одновременно и сохраняется «смысл» программы.

3 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Одна из технологий параллелизации программы – векторизация циклов. C[1] = A[1]+B[1] C[2] = A[2]+B[2] C[3] = A[3]+B[3] C[4] = A[4]+B[4] A[1] A[2] A[3] A[4] A[1] A[2] A[3] A[4] Векторизация B[1] B[2] B[3] B[4] B[1] B[2] B[3] B[4] + = C[1] C[2] C[3] C[4] C[1]C[2]C[3]C[4]

4 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Типичная векторная инструкция представляет собой операцию над двумя векторами в памяти или в регистрах фиксированной длины. Данные векторные регистры могут быть загружены из памяти за одну операцию или по частям. Векторизация - это компиляторная оптимизация, которая заменяет скалярный код на векторный. Т.е. эта оптимизация «упаковывает» данные в вектора и заменяет скалярные операции на операции с векторами (пакетами). A(1:n:k) – секция массива в Фортране. for(i=0;i<U,i++) { for(i=0;i<U;i+=vl) { S 1 : lhs 1 [i] = rhs 1 [i]; S1: lhs 1 [i:i+vl-1:1] = rhs 1 [i:i+vl-1:1]; … => … S n : lhs n [i] = rhs n [i]; S n : lhs n [i:i+vl-1:1] = rhs n [i:i+vl+1:1]; } }

5 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. MMX,SSE Векторные инструкции и векторизация Первоначально была предложена технология MMX. MMX (Multimedia Extensions) – набор инструкций, выполняющих характерные для процессов кодирования/декодирования потоковых аудио/видео данных действия. MMM0-MMM7 64 битные регистры для работы с целыми числами MMM0-MMM7 64 битные регистры для работы с целыми числами концепция пакетов, каждый из этих регистров мог хранить концепция пакетов, каждый из этих регистров мог хранить 2 – 32 битных целых числа 2 – 32 битных целых числа 4 - 16 битных 4 - 16 битных 8 - 8 битных 8 - 8 битных 47 инструкций, которые деляться на несколько груп: перемещение данных перемещение данных арифметические арифметические сравнения сравнения конвертации конвертации логические логические распаковки распаковки сдвига сдвига пустые инструкции получения состояния пустые инструкции получения состояния

6 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. SSE (Streaming SIMD Extensions, потоковое SIMD-расширение процессора) — набор инструкций позволяющий работать с множеством данных – SIMD(Single Instruction, Multiple Data, Одна инструкция — множество данных). SSE включает в себя : 8 128-битных регистров (xmm0 до xmm7) 8 128-битных регистров (xmm0 до xmm7) набор инструкций, который производит операции со скалярными и упакованными типами данных. набор инструкций, который производит операции со скалярными и упакованными типами данных. Технология EMM64T добавляла к этому набору еще 8 128 битных регистра (xmm8 до xmm15). SSE2,SSE3,SSEE3,SSE4 – последующие расширения этой идеи. SSE2 добавил тип упакованных данных с плавающей точкой двойной точности. AVX новое AVX новое расширение системы команд (Advanced vector extensions) AVX предоставляет различные улучшения, новые инструкции и новую схему кодирования машинных кодов. Размер векторных регистров SIMD увеличивается с 128 до 256 бит. Регистры YMM0-YMM15 Существующие 128-битные инструкции используют младшую половину YMM регистров.

7 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Данные различных типов могут быть упакованы в векторные регистры следующим образом: Данные различных типов могут быть упакованы в векторные регистры следующим образом: Упакованный тип данных Длина вектора Число битов на элементОбласть значений типа signed bytes168-2**7 до 2**7-1 unsigned bytes1680 до 2**8-1 signed words816-2**15 до 2**15-1 unsigned words8160 до 2**16 signed doublewords432-2**31 до 2**31-1 unsigned doublewords4320 до 2**32-1 signed quadwords264-2**63 до 2*63-1 unsigned quadwords2640 до 2**64-1 single-precision fps4322**-126 до 2**127 double-precision fps2642**-1022 до 2**1023 Выбор подходящего для вычислений типа данных может существенно сказаться на производительности приложения.

8 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. 8 Optimization with Switches SIMD – SSE, SSE2, SSE3, SSE4.2 Support 16x bytes 8x words 4x dwords 2x qwords 1x dqword 4x floats 2x doubles MMX* SSE SSE4.2 SSE3 SSE2 SSE4.2 SSE3 SSE2 * MMX actually used the x87 Floating Point Registers - SSE, SSE2, and SSE3 use the new SSE registers

9 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Группы иструкций: Инструкции перемещения данных: (data movement instructions) : Instruction Suffix Description movdqa перемещение выравненного двойного четверного слова (double quadword) movdqu перемещение невыравненного двойного четверного слова mova [ ps, pd ] перемещение выравненого вещественного movu [ ps, pd ] перемещение невыравненного вещественного movhl [ ps ] перемещение верхней части упакованного вещественного вниз movlh [ ps ] перемещение нижней части упакованного вещественного вверх movh [ ps, pd ] перемещение верхней части упакованного вещественного movl [ ps, pd ] перемещение нижней части упакованного вещественного mov [ d, q, ss, sd ] перемещение скалярных данных lddqu перемещение невыравненного двойного четверного слова mov dup перемещение и дублирование pextr [ w ] извлечение слова pinstr [ w ] вставка слова pmovmsk [ b ] перемещение маски movmsk [ ps, pd ] перемещение маски Инструкции для перемещения выравненных (aligned) данных не могут использоваться для работы с адресами памяти не выравнеными на 16. 10/17/10

10 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Целочисленные арифметические инструкции : Instruction Suffix Description padd [ b, w, d, q ] векторное сложение (знаковые и беззнаковые) psub [ b, w, d, q ] векторное вычитание (знаковые и беззнаковые) padds [ b, w ] векторное сложение с насыщением (знаковые) paddus [ b, w ] векторное сложение с насыщением (беззнаковые) psubs [ b, w ] векторное вычитание с насыщением (знаковые) psubus [ b, w ] векторное вычитание с насыщением (беззнаковые) pmins [ w ] векторный минимум (знаковые) pminu [ b ] векторный минимум (беззнаковый) pmaxs [ w ] векторный максимум (знаковый) pmaxu [ b ] векторный максимум (беззнаковый) 10/17/10

11 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Арифметические операции с вещественными числами : Instruction Suffix Description add [ ss, ps, sd, pd ] сложение div [ ss, ps, sd, pd ] деление min [ ss, ps, sd, pd ] минимум max [ ss, ps, sd, pd ] максимум mul [ ss, ps, sd, pd ] умножение sqrt [ ss, ps, sd, pd ] квадратный корень sub [ ss, ps, sd, pd ] вычитание rcp [ ss, ps] приблизительное обратное rsqrt [ ss, ps] приблизительный обратный квадратный корень Идиоматические арифметические инструкции : Instruction Suffix Description pang [ b, w ] векторное среднее с округлением (беззнаковые) pmulh/pmulhu/pmull [ w ] векторное умножение psad [ bw ] векторная сумма абсолютных разниц (беззнаковые) pmadd [ wd ] векторное умножение и сложение (знаковые) addsub [ ps, pd ] вещественное сложение/вычитание hadd [ ps, pd ] вещественное горизонтальное сложение hsub [ ps, pd ] вещественное горизонтальное вычитание 10/17/10

12 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Логические инструкции : Instruction Suffix Description pand побитовый логический AND pandn побитовый логический AND-NOT por побитовый логический OR pxor побитовый логический XOR and [ ps, pd ] побитовый логический AND andn [ ps, pd ] побитовый логический AND-NOT or [ ps, pd ] побитовый логический OR xor [ ps, pd ] побитовый логический XOR Инструкции сравнения : Instruction Suffix Description pcmp [ b, w, d ] векторное сравнение cmp [ ss, ps, sd, pd ] вещественное сравнение Здесь обозначает операцию сравнения. lt – меньше, gt – больше, eq - равно 10/17/10

13 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Конвертирующие инструкции : Instruction Suffix Description packss [wb, dw] упаковывать с насыщением (знаковые) paсkus [wb] упаковывать с насыщением (беззнаковые) cvt конвертация cvtt конвертация с усечением Инструкции сдвига : Instruction Suffix Description psll [ w, d, q, dq ] логический сдвиг влево psra [w, d] арифметический сдвиг вправо psrl [ w, d, q, dq ] правый логический сдвиг Перестановочные (shuffle) инструкции : Instruction Suffix Description pshuf [ w, d ] векторная перестановка pshufh [w] векторная перестановка верхней части pshufl [w] векторная перестановка нижней части ырга [ ps, pd ] перестановка 10/17/10

14 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Расспаковывающие инструкции : Instruction Suffix Description punpckh [bw, wd, dq, qdq] распаковать верхнюю часть punpckl [bw, wd, dq, qdq] распаковать нижнюю часть unpckh [ps, pd] распаковать верхнюю часть unpckl [ps, pd] распаковать нижнюю часть Инструкции работы с кэшем : Instruction Suffix Description movnt [ ps, pd, q, dq ] перемещать выравненные не временные данные prefetch подрузить в кэш Управляющие состоянием инструкции Обычно используются опреционной системой. 10/17/10

15 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. 15 Три набора опций для использования процессорно-специфических расширений 1.Опции –x например –xSSE4_1 –Проводит проверку процессора –Ошибка времени выполнения в случае запуска программы на прцессоре отличном от указанного в опции 2.Опции –m например –mSSE3 –Нет проверки –Падение программы при выполнении специфической процессорной инструкции в случае запуска на процессоре не поддерживающем указанное расширение 3.Опции –ax например –axSSE4_2 –Автоматический выбор оптимального варианта – наличие кода для разных векторных расширений –Проверка процессора доступна только для Интеловских процессоров –Для не Интеловского прцессора используется умолчательный код –Умолчательная опция –mSSE2

16 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Типичная векторная инструкция представляет собой операцию над двумя векторами в памяти или в регистрах фиксированной длины. Данные векторные регистры могут быть загружены из памяти за одну операцию или по частям. Описание основ SSE технологии можно прочитать в CHAPTER 10 PROGRAMMING WITH STREAMING SIMD EXTENSIONS (SSE) документа «Intel 64 and IA-32 Intel Architecture Software Developer's Manual» (Volume 1) Microsoft Visual Studio поддерживает набор SSE интринсиков, которые позволяют напрямую использовать SSE инструкции из С/C++ кода. Это позволяет осуществлять векторизацию вручную. Для этого необходимо подключить xmmintrin.h, который определяет тип __m128 (это векторный тип) и операции с ним. Допустим мы хотим векторизовать вручную цикл: for(i=0;i<N;i++) C[i]=A[i]*B[i]; Для этого необходимо : 1) организовать/заполнить векторные переменные 2) запустить интринсик для умножения векторных переменных 3) скопировать результаты вычислений в память (Для экпериментов использовался Intel компилятор версии 12.0) (Использовать icl –help для получения опций компилятора. )

17 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. #include #define N 40 int main() { float a[N][N][N],b[N][N][N],c[N][N][N]; int i,j,k,rep; __m128 *xa,*xb,*xc; for(i=0;i<N;i++) for(j=0;j<N;j++) for(k=0;k<N;k++) { a[i][j][k]=1.0; b[i][j][k]=2.0; } for(rep=0;rep<10000;rep++) { #ifdef PERF for(i=0;i<N;i++) for(j=0;j<N;j++) for(k=0;k<N;k+=4) { xa=(__m128*)&(a[i][j][k]); xb=(__m128*)&(b[i][j][k]); xc=(__m128*)&(c[i][j][k]); *xc=_mm_mul_ps(*xa,*xb); } #else for(i=0;i<N;i++) for(j=0;j<N;j++) for(k=0;k<N;k++) c[i][j][k]=a[i][j][k]*b[i][j][k]; #endif } printf("%f\n ",c[21][11][18]); } Пример, иллюстрирующий векторизацию с помощью SSE интринсиков. icl -Od test.c -Fetest1.exe icl -Od test.c -DPERF - Fetest_opt.exe time test1.exe 2.000000 CPU time for command: 'test1.exe' real 3.406 sec user 3.391 sec system 0.000 sec time test_opt.exe 2.000000 CPU time for command: 'test_opt.exe' real 1.281 sec user 1.250 sec system 0.000 sec

18 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Полученный прирост производительности - 2.7x. Для работы некоторых векторных инструкций необходимо, чтобы адреса в памяти были выравнены на 16. В нашем тесте это получилось случайно, в реальном случае нужно об этом заботиться. Тест оптимизированный компилятором показывает следующий результат: icl test.c -Qvec_report3 -Fetest_intel_opt.exe time test_intel_opt.exe 2.000000 CPU time for command: 'test_intel_opt.exe' real 0.328 sec user 0.313 sec system 0.000 sec

19 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Допустимость векторизации Векторизация – перестановочная оптимизация. Операции меняют порядок выполнения. Перестановочные оптимизации допустимы, если не изменяется порядок зависимостей. Таким образом мы получили критерий допустимости векторизации в терминах зависимостей. Простейший вариант – зависимостей в векторизуемом цикле нет. Зависимости в векторизуемом цикле есть, но их порядок после векторизации совпадает с порядком в невекторизованном цикле.

20 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. /Qvec-report[n] control amount of vectorizer diagnostic information n=0 no diagnostic information n=1 indicate vectorized loops (DEFAULT) n=2 indicate vectorized/non-vectorized loops n=3 indicate vectorized/non-vectorized loops and prohibiting data dependence information n=4 indicate non-vectorized loops n=5 indicate non-vectorized loops and prohibiting data dependence information Использование: icl -c -Qvec_report3 loop.c Примеры диагностики: C:\loops\loop1.c(5) (col. 1): remark: LOOP WAS VECTORIZED. C:\loops\loop3.c(5) (col. 1): remark: loop was not vectorized: vectorization possible but seems inefficient. C:\loops\loop6.c(5) (col. 1): remark: loop was not vectorized: nonstandard loop is not a vectorization candidate. 10/17/10

21 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Фортран акктивно используется в описании векторизации, поскольку имеет удобное понятие секции массива. В упрощенном виде: DO I=1,N A(I)=… END DO при векторизации переводится в DO I=1,N/K A(I:I+K)=… END DO где K – число элементов матрицы A размещаемых в векторном регистре. Наглядным критерием возможности векторизации является то факт, что введение секций массива не порождает зависимостей. DO I=1,N DO I=1,N/K A(I)=A(I)+C => A(I:I+K) = A(I:I+K)+C END DO Может быть векторизован. DO I=1,N DO I=1,N/K A(I+1)=A(I)+C => A(I+1:I+1+K)=A(I:I+K)+C END DO Не может быть векторизован.

22 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Предположение: Цикл можно векторизовать, если дистанция для зависимости >= K, где K – количество элементов массива, входящих в векторный регистр. Проверяем утверждение с помощью компилятора: ifort test.F90 -o a.out –vec_report3 echo ------------------------------------- ifort test.F90 -DPERF -o b.out –vec_report3./build.sh test.F90(11): (col. 1) remark: loop was not vectorized: existence of vector dependence. ------------------------------------- test.F90(11): (col. 1) remark: LOOP WAS VECTORIZED. PROGRAM TEST_VEC INTEGER,PARAMETER :: N=1000 #ifdef PERF INTEGER,PARAMETER :: P=4 #else INTEGER,PARAMETER :: P=3 #endif INTEGER A(N) DO I=1,N-P A(I+P)=A(I) END DO PRINT *,A(50) END

23 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Факторы, влияющие на производительность векторизованного кода. Рассмотрим такой тест: INTEGER :: A(1000),B(1000) INTEGER I,K INTEGER, PARAMETER :: REP = 500000 A = 2 DO K=1,REP CALL ADD(A,B) END DO PRINT *,SHIFT,B(101) CONTAINS SUBROUTINE ADD(A,B) INTEGER A(1000),B(1000) INTEGER I !DEC$ UNROLL(0) DO I=1,1000-SHIFT B(I) = A(I+SHIFT)+1 END DO END SUBROUTINE END

24 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. ifort test1.F90 -O2 -Ob0 /fpp /DSHIFT=0 -Fea.exe -Qvec_report >a.out 2>&1 ifort test1.F90 -O2 -Ob0 /fpp /DSHIFT=1 -Feb.exe -Qvec_report >b.out 2>&1 %TIME% a.exe %TIME% b.exe Скомпилируем исходный тест, передав в программу разные значения переменной SHIFT. Получим: C:\users\aanufrie\students\continuous2>C:\u4win\bin\x86_win32\time.exe a.exe 0 3 CPU time for command: 'a.exe' real 0.125 sec user 0.094 sec system 0.000 sec C:\users\aanufrie\students\continuous2>C:\u4win\bin\x86_win32\time.exe b.exe 1 3 CPU time for command: 'b.exe' real 0.297 sec user 0.281 sec system 0.000 sec

25 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. ifort test1.F90 -O2 -Ob0 /fpp /DSHIFT=0 /Fas -Ob0 -Qvec_report3 -S –Fatest0.s ifort test1.F90 -O2 -Ob0 /fpp /DSHIFT=1 /Fas -Ob0 -S -Qvec-report3 –Fatest1.s Для данного цикла имеем для быстрого случая:.B2.5: ; Preds.B2.5.B2.4 $LN83: ;;; B(I) = A(I+SHIFT)+1 movdqa xmm1, XMMWORD PTR [eax+ecx*4] ;17.11 $LN84: paddd xmm1, xmm0 ;17.4 $LN85: movdqa XMMWORD PTR [edx+ecx*4], xmm1 ;17.4 $LN86: add ecx, 4 ;16.3 $LN87: cmp ecx, 1000 ;16.3 $LN88: jb.B2.5 ; Prob 99% ;16.3

26 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Для данного цикла имеем для медленного случая:.B2.5: ; Preds.B2.5.B2.4 $LN81: ;;; B(I) = A(I+SHIFT)+1 movdqu xmm1, XMMWORD PTR [4+eax+ecx*4] ;17.11 $LN82: paddd xmm1, xmm0 ;17.4 $LN83: movdqa XMMWORD PTR [edx+ecx*4], xmm1 ;17.4 $LN84: add ecx, 4 ;16.3 $LN85: cmp ecx, 996 ;16.3 $LN86: jb.B2.5 ; Prob 99% ;16.3 MOVDQA—Move Aligned Double Quadword MOVDQU—Move Unaligned Double Quadword

27 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Производительность векторизованного цикла зависит от того, каким образом векторизуемые объекты расположены в памяти. Поэтому первый аспект имеющий огромное значение для производительности программы – выравнивание данных в памяти. Выравнивание структур данных (Data Structure Alignment) это метод с помощью которого данные располагаются и доступаются в компьютерной памяти. Это понятие заключает в себе два различных, но взаимосвязанных вопроса: выравнивание данных (Data alignment) и заполнение структур данных (Data structure padding). Выравнивание данных определяет, как те или иные данные расположены относительно границ памяти. Этот факт как правило связан с типом данных. Заполнение структур данных подразумевает вставку безымянных полей в структуру данных, для того чтобы сохранить относительное выравнивание полей структуры.

28 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Информация о выравнивании может быть получена с помощью интринсика __alignof__. Размер переменной данного типа и выравнивание по умолчанию может зависеть от типа компилятора. printf("int: sizeof=%d align=%d\n",sizeof(a),__alignof__(a)); Выравнивание для 32 битного Интеловского C++ компилятора: bool sizeof = 1 alignof = 1 wchar_t sizeof = 2 alignof = 2 short int sizeof = 2 alignof = 2 int sizeof = 4 alignof = 4 long int sizeof = 4 alignof = 4 long long int sizeof = 8 alignof = 8 float sizeof = 4 alignof = 4 double sizeof = 8 alignof = 8 long double sizeof = 8 alignof = 8 void* sizeof = 4 alignof = 4 Те же самые правила используются и при выравнивании массивов. Существует возможность выравнять объект необходимым образом: __declspec(align(16)) float x[N]; 10/17/10

29 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. struct foo { bool a; short b; long long c; bool d; }; 10/17/10 struct foo { bool a; char pad1[1]; short b; char pad2[4]; long long c; bool d; char pad3[7]; }; Порядок полей в структуре оказывает влияние на размер объекта производного типа. С целью уменьшения размера объекта рекомендуется размещать поля в объекте в порядке уменьшения их размера. Можно использовать __declspec для выравнивания полей структуры. typedef struct aStuct{ __declspec(align(16)) float x[N]; __declspec(align(16)) float y[N]; __declspec(align(16)) float z[N]; };

30 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Производительность векторизованного цикла зависит от того как обрабатываются векторные регистры, поэтому в общем случае скалярный цикл, работающий с одним массивом DO I=K,N A(I)=… END DO векторизуется следующим образом: if(! N<K) { t1=N-K+1; /* общее кол-во итераций */ t2=&A[K]&15; if(t2!=0) { /* проверяем выравнен ли объект в памяти */ t2=(16-t2)/SIZEOF(array_element); } if(t1<4+t2) { /* нечего векторизовать */ t3=0; goto TAIL; } t3=t1-((t1-t2)&3)); /* кол-во векторизованных итераций */ DO I=1,t2 /* головной цикл */ A[I+K-1]=… END DO DO I=t2+1,t3,4 /* векторизованный цикл */ A[I+K-1:I+K+3]=… END DO TAIL: DO I=t3+1,t1 /* хвостовой скалярный цикл */ A[I+K-1]=… END DO }

31 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Каким образом правильное выравнивание может помочь в случае скалярного цикла, обрабатывающего несколько массивов? void Calculate(float * restrict a,float * restrict b,float * restrict c,int n) { int i; for(i=0;i<n;i++) { a[i] = ((a[i]*a[i])+(b[i]*b[i]))/(c[i]*c[i]); } return; } icl -S vec7.c -Qstd=c99 -QxSSE4.2 -O3 Легко найти векторизованный цикл и убедиться, что используются векторные инструкции для доступа к невыравненной памяти..B1.20:: ; Preds.B1.18.B1.20 movss xmm2, DWORD PTR [rcx+r9*4] ;1.6 movss xmm0, DWORD PTR [rdx+r9*4] ;1.6... В компиляторе есть возможность предупредить компилятор о том, что переданные в функцию аргументы будут выравнены: __assume_aligned(a,16);

32 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Добавив в нашу функцию следующие строки __assume_aligned(a,16); __assume_aligned(b,16); __assume_aligned(c,16); мы получим код без головного выравнивающего цикла, использующий инструкции movaps для доступа к памяти. Оценим выгодность полученного кода добавив к нашей функции функцию main следующего вида: #include #define N 1000 extern void Calculate(float *x,float *y,float *z,int n); int main() { __declspec(align(16)) float x[N]; __declspec(align(16)) float y[N]; __declspec(align(16)) float z[N]; int i,rep; for(i=0;i<N;i++) { x[i] = 1;y[i] = 1; z[i] = 1; } for(rep=0;rep<10000000;rep++) { Calculate(&x[0],&y[0],&z[0],N); } printf("x[0]=%f\n",x[0]); } Icl main.c vec8.c -Qstd=c99 -QxSSE4.2 -O3 -Fevec8 => 5.43s icl main.c vec7.c -Qstd=c99 -QxSSE4.2 -O3 –Fevec7 => 5.57s

33 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Векторизация может ухудшить производительность маленьких циклов. INTEGER I,J,A(100) INTEGER,VOLATILE :: K,N K=1 N=11 DO J=1,1000000 DO I=K,N A(I)=J END DO PRINT *,A(55) END Без векторизации тест выполняется 0.10s а с векторизацией 0.13s. Почему так происходит? Цикл в примере разложится на 3 части: от 2 до 5 – скалярный цикл (3 итерации) от 5 до 8 – векторизированный цикл (1 итерация) от 9 до 11 – скалярный цикл (3 итерации)

34 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Векторизация в общем случае может быть выполнена не только на внутреннем цикле. Если мы имеем вложенное множество циклов и внутренний цикл не может быть векторизован из-за существования каких-либо зависимостей, то можно пытаться векторизовать внешний цикл: DO I=1,N DO J=1,K A(J,I) =.. END DO  Векторизация DO I=1,N DO J=1,K A(J,I:I+P-1)=… END DO Будет ли полезной такая оптимизация?

35 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Векторизация и многоверсионный код. Дополнительная возможность для улучшения производительности – формирование многоверсионного кода, т.е. кода включающего проверки времени выполнения. Примеры случаев, когда это может работать: void sub(int *a,int *b) { int i; for(i=0;i<1000;i++) a[i]=b[i]; } void sub(int *a,int n) { int i; for(i=0;i<1000;i++) a[i]=a[i+n]; } Можно проверить работает ли многоверсионная векторизация для gcc или интеловского компилятора.

36 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Существуют полезные прагмы, которые вы можете использовать для улучшения эффективности векторизации: __declspec(align(n)) – указывает компилятору выравнивать переменную на n-байтовую границу #pragma ivdep Предлагает игнорировать предполагаемую векторную зависимость #pragma vector{aligned|unaligned|always} Определяет как векторизивать цикл #pragma novector Цикл не должен быть векторизован Аналоги для Фортрана !DEC$ IVDEP !DEC$ VECTOR ALWAYS !DEC$ NOVECTOR

37 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. Интеловский компилятор пытается объединить цикловые оптимизации, векторизацию, параллелизацию и оценочную модель в одном компоненте для того чтобы достичь наилучшего взаимодействия между этими оптимизациями. Сначала с помощью различных оптимизаций компилятор пытается улучшить работу с памятью, разбивает циклы, переставляет, векторизует их, развертывает, объединяет. Векторизуется только внутренний цикл.

38 Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property of their respective owners. 10/17/10 Спасибо за внимание!


Download ppt "Software & Services Group, Developer Products Division Copyright© 2010, Intel Corporation. All rights reserved. *Other brands and names are the property."

Similar presentations


Ads by Google