SlideShare uma empresa Scribd logo
1 de 37
Эффективное использование
   x86-совместимых CPU
   Многопоточность, векторные расширения




         Алексей Тутубалин
            lexa@lexa.ru
          CTO @LibRaw LLC
Производительность CPU 2005-2012:

Практически постоянна?          Выросла в 32-64 раза?
Производительность CPU =        • Многоядерность
 частота * (число инструкций       – С 2005 по 2012: рост в 4-8
на такт)                             раз
• Тактовая частота              • SSE, AVX
   2005 – 2.5-3.6 Ghz             –    2005: 2 операции на такт
   2012 – 1.8-3.5 Ghz             –    2012: 16 операций на такт
• Инструкции/такт
   после Intel Core2 => роста
   очень медленный
Локальная параллельность
• Только в хотспотах
  – Замена обычных циклов - параллельными
  – Замена обычных команд – векторными (SIMD:
    SSE, AVX)
• Сопутствующие изменения
  – Редизайн/рефакторинг структур данных
  – Изменения в алгоритмах
ЛОКАЛЬНАЯ МНОГОПОТОЧНОСТЬ
Схема работы
• Fork/join на месте
  длинных циклов
• Накладные расходы
  – n*1-10µsec на каждый поток
• Методы реализации
  – Полуавтоматически: OpenMP
  – Вручную: threading-библиотеки
OpenMP
• Простой синтаксис: #pragma в
  последовательном коде
#pragma omp parallel for
for(i=0;i<N;i++)
     a[i] = b[i]+c[i];
• Возможности: reduction, atomics, critical
  sections, режим доступа к переменным:
sum=0.0;
#pragma omp parallel for reduction(+:sum)
for(i=0;i<N;i++)
     sum+=vector[i];
OpenMP
• Чужеродность для С++
  – Нет поддержки exceptions
• Не все компиляторы поддерживают
• Бывают ошибки в рантайме (или
  компиляторе)
• Альтернатива: Cilk Plus (Intel C++, gcc 4.8
  branch)
Параллельные библиотеки
Intel TBB: суммирование вектора
Итого
1. Это работает !
2. Эффективность:
  – Обычно 75-85% (3-3.5x speedup на 4-core)
  – >90% для «гигабайт» данных
3. Дополнительный код:
  – 1-20 строк на каждую точку оптимизации
SIMD-КОМАНДЫ (SSE, AVX)
SSE/AVX: что это такое?
• SSE: одновременные операции
  над 128-битными векторами
addps xmm0,xmm1
означает:
for(i=0;i<4;i++)
      xmm0[i]+=xmm1[i];
• AVX: вектор 128 или 256 бит, 3-адресность:
vaddps ymm0,ymm1,ymm2
означает:
for(i=0;i<8;i++)
      ymm0[i]=ymm1[i]+ymm2[i];
X86: много сортов SIMD
• Под что код делать будем?
  – 6 версий SSE
  – 2 версии AVX
• Чем новее версия
  – Тем больше вкусных команд
  – И тем уже поддержка
SSE/AVX: что умеет
Что есть:                 Что есть:
• Команды                 • 16 (8) регистров
  – Load/store            • Типы данных
  – Арифметика                – Целые: 8, 16, 32, 64 бит
  – Сравнения, min, max       – Плавающие: 32, 64
  – Конверсия типов
                           Чего нет:
  – Битовые операции
                           • Flow control
  – Перестановка
    элементов вектора • Scatter/gather
  – Dot
    Product, CRC32, AES, S
    TRCMP
SSE/AVX: упаковка данных
Стандартный ООП-вариант        Structure of Arrays (SoA)
Array Of Structures (AoS)
                            class foo_vector {
class foo {
                              vector<float> x,y,z;
  float x,y,z;
                            };
void calc_z(){z=A*x+B*y;}
                            foo_vector::calc_z()
};
                             for(..) z[i]=A*x[i]+B*y[i];
vector<foo> fv(..);
for(…..) fv[i].calc_z();
                            calc_z() – хорошо векторизуется:
• for(..)calc_z() – плохо      – 2 чтения
  векторизуется:               – 3 оп. арифметики
    – 4-8 чтений               – 1 запись
    – 3 оп. арифметики
    – 4 записи
SSE: выравнивание
• До Intel Core-i7:
  – aligned (16 байт) load/store – сильно быстрее
    (~4 раза для Core2Duo)
• Начиная с Core-i7:
  – Почти нет разницы (<10%)
С/C++: выравнивание
• Переменные и поля в структурах:
Gcc: int bar[64] __attribute_((aligned(16)));
MSVC:__declspec(align(16)) float baz[32];
• Простые аллокации:
   – MSVC: _aligned_malloc(size, align)/_aligned_free()
   – Gcc: _mm_malloc(size, align)/_mm_free()

• STL: выравнивающий аллокатор:
std::vector<T, AlignmentAllocator<T, 16> >                foo;

Все элементы вектора выровнены на 16:
class __attribute__ ((aligned (16))) Foo {
      __attribute__ ((aligned (16))) float bar[4];
};
std::vector<Foo, AlignmentAllocator<Foo, 16> > baz;
У последнего примера – проблемы с Microsoft STL (починено в VS2012)
Откуда берется SSE/AVX-код?
1. Генерирует C/C++ компилятор
   (автоматическая векторизация)
2. Пишется руками
  – макросы компилятора (compiler intrinsics)
  – ассемблер
Compiler intrinsics: нудную работу
     должен делать компилятор
Стандартные типы данных            Макросы для команд
                                   __m128
__m128 => SSE-регистр              _mm_add_ps(__m128,__m128)
(float[4] или int16[8] или еще 6
вариантов)                         => addps (или vaddps)
                                   Компилятор:
__m128d => double[2]               • Распределяет регистры
                                   • Подставляет адреса C-
Типы AVX-256:                        переменных
__m256 => float[8]                 • Генерирует код под целевую
                                     архитектуру (SSE, AVX)
__m256d => double[4]
                                   • Может переупорядочить
                                     команды
Ручной код: compiler intrinsics
C: 277 Mpix/sec (8.8 Gb/sec)       SSE/AVX: 584 Mpix/sec (18.6 Gb/s)
компилятор частично векторизовал
SIMD: Итого
1.   Это не больно!
2.   Выигрыш в 2-4 раза - запросто
3.   Трудный старт
4.   Где брать информацию:
     – Intel Software Developers Manual, Vol 2A & 2B
     – MSDN: руководство по Visual Studio, много
       мелких примеров по _mm-макросам
     – Собирать по крупицам… 
ПАРАЛЛЕЛЬНЫЕ/SIMD ЯЗЫКИ
Intel SPMD Program Compiler (ISPC)
• SPMD – Single Program, Multiple Data
• Метафора: «пишем программу для одного SIMD-
  элемента, компилятор расширит на весь вектор»
• x86: SSE2, SSE4, AVX, AVX2, Xeon Phi
• Поддерживается Intel: BSD-license, opensource,
  http://ispc.github.com
ISPC: пример и синтаксис
Сложение векторов   Расширение C:
                    • uniform – разделяемая копия
                      переменной на все
                      параллельные/SIMD потоки
                      varying – приватная копия
                    • foreach/foreach_tiled – SIMD-
                      цикл (тело цикла векторизуется)
                      запускается
                    • launch - запуск задачи
                    • Встроенные переменные:
                      programIndex – номер SIMD-
                      lane
                      programCount – ширина SIMD
                      taskIndex – номер задачи
                    • Далее – см. документацию
ISPC: многопоточность
ISPC: практика
OpenCL
• Стандарт для «гетерогенных вычислений»
• Платформы: CPU/GPU
• Особенности
  –   Компиляция на лету
  –   Двойная буферизация
  –   Отдельный внешний рантайм
  –   Громоздкий API
• Применение
  – Для больших объемов вычислений
  – Если планируется переход на GPU-расчеты
Позитив
• Ускорение в 10-15 раз – достижимо
• Вероятно, потребуется рефакторинг
  Но только один раз:
  – Параллельный код неплохо масштабируется
  – Рефакторинг для CPU => годится для GPU
• Но лучше – сразу писать эффективно, помня
  о грядущей паралельности
Презентация (со ссылками) доступна:
www.slideshare.net/AlexTutubalin

Я иногда пишу на эти темы:
blog.lexa.ru/tags/sse




СПАСИБО ЗА ВНИМАНИЕ!
ВОПРОСЫ?
ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ
Bandwidth vs Latency
             Bandwidth    Latency
RAM,1980       13 MB/s      225 ns    • Случайный доступ -
RAM, 2000     1600 MB/s     52 ns
               (~125x)     (~4.5x)
                                        медленный
RAM, 2012    12800 MB/s     35ns        – «Память – это новый диск»
              (~1000x)     (~6.5x)      – «Диск – это новая лента»
HDD, 1980     0.6 MB/s      48 ms
HDD, 2000      86 MB/s     5.7 ms
                                      • У CPU – то же самое!!
               (~150x)     (~8.5x)    • Кэши – немного спасают
HDD,2012      300 MB/s      ~5 ms
               (~500x)      (~10x)    • LAN – приятное
10 Mbit        1 MB/s     3000 µsec     исключение из общего
Ethernet
                                        правила
56Gbit       ~5000 MB/s    0.7 µsec
Infiniband     (5000x)     (~4300x)
BW/Latency: решения
• Нужно не зависеть от Latency:
  – Последовательный код
  – Нет зависимости по данным
  – Последовательный доступ к памяти (и диску)
  – Prefetch в кэши
• А любая случайность – зло:
  – Обращение по указателю
  – Синхронизация (!)
  – Не предсказанный условный переход
  – Случайный disk seek
Векторизация С/C++: алиасинг
Сложение двух векторов:
void sum_vec(float *s1,float *s2, float *d, int N){
       for(int i=0;i<N;i++)
                d[i] = s1[i]+ s2[i];
}
Вызов:
float A[SZ]; sum_vec(A,A+1,A+2,SZ-2);
Решение: restrict (C99), __restrict__(gcc C++), __restrict (MSVC):
void sum_vec(float * __restrict__ s1,
float* __restrict__ s2, float* __restrict__ d….
Но:
• Алиасинг бывает и на this
• В библиотечных классах – может не быть указан restrict
Векторизация в C++ компиляторах
• «Обычный код» (после базовых правок выравнивания и
  алиасинга):
   – Личный опыт: ускорения «в разы» компилятор не дает,
     нужно вручную.
   – Чужой опыт: «An Evaluation of Vectorizing Compilers» (2011)
     http://polaris.cs.uiuc.edu/~garzaran/doc/pact11.pdf
     Для кода Media Bench II получили:
      • Intel C++/GCC: среднее ускорение 1.2 раза.
      • Ручной ассемблерный код: ускорение 2.7 раза.
• Нужны серьезные правки кода, см. например
  Program Optimization Trough Loop Vectorization
  https://wiki.engr.illinois.edu/download/attachments/114
  688007/9-Vectorization.pdf
Модификация кода для успешной
        векторизации
Не векторизуется      Векторизуется
for(i=0;i<LEN;i++){   for(i=0;i<LEN;i++){
 sum = 0.0;            sum[i] = 0.0;
 for(j=0;j<LEN;j++)    for(j=0;j<LEN;j++)
     sum+=A[j][i];         sum[i]+=A[j][i];
 B[i] = sum;           B[i] = sum[i];
}                     }
ISPC: ускорение
(для поставляемых примеров)
OpenCL: корни в GPGPU
• Много отдельных
  потоков (Work Items)
• Объединенных в блоки
  с быстрой общей
  памятью (Work Groups)
• Блоков много, порядок
  исполнения не
  определен
• Общая глобальная
  (медленная) память
OpenCL: сложение векторов

Mais conteúdo relacionado

Mais procurados

Алексей Рагозин (Deutsche Bank)
Алексей Рагозин (Deutsche Bank)Алексей Рагозин (Deutsche Bank)
Алексей Рагозин (Deutsche Bank)
Ontico
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Mikhail Kurnosov
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandra
odnoklassniki.ru
 
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Mikhail Kurnosov
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Mikhail Kurnosov
 
Introduction in CUDA (1-3)
Introduction in CUDA (1-3)Introduction in CUDA (1-3)
Introduction in CUDA (1-3)
Alexander Mezhov
 

Mais procurados (20)

Алексей Рагозин (Deutsche Bank)
Алексей Рагозин (Deutsche Bank)Алексей Рагозин (Deutsche Bank)
Алексей Рагозин (Deutsche Bank)
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSU
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPВебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandra
 
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
 
CUDA Best Practices (2-3)
CUDA Best Practices (2-3)CUDA Best Practices (2-3)
CUDA Best Practices (2-3)
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
 
Introduction in CUDA (1-3)
Introduction in CUDA (1-3)Introduction in CUDA (1-3)
Introduction in CUDA (1-3)
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, Paral...
 

Semelhante a Эффективное использование x86-совместимых CPU (Алексей Тутубалин)

Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Mikhail Kurnosov
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
Technopark
 
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Vadim Kosov
 
Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)
Ontico
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)
Ontico
 
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
Ontico
 
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими рукамиАндрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
IBS
 
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
Ontico
 

Semelhante a Эффективное использование x86-совместимых CPU (Алексей Тутубалин) (20)

Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 
введение в Gpu
введение в Gpuвведение в Gpu
введение в Gpu
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
 
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
 
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
 
Cpp
CppCpp
Cpp
 
Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)
 
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)
 
Пути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияПути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обучения
 
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
NVMf: 5 млн IOPS по сети своими руками / Андрей Николаенко (IBS)
 
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими рукамиАндрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
Андрей Николаенко, IBS. NVMf: 5 млн IOPS по сети своими руками
 
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)
 

Mais de Ontico

Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Ontico
 

Mais de Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 

Эффективное использование x86-совместимых CPU (Алексей Тутубалин)

  • 1. Эффективное использование x86-совместимых CPU Многопоточность, векторные расширения Алексей Тутубалин lexa@lexa.ru CTO @LibRaw LLC
  • 2. Производительность CPU 2005-2012: Практически постоянна? Выросла в 32-64 раза? Производительность CPU = • Многоядерность частота * (число инструкций – С 2005 по 2012: рост в 4-8 на такт) раз • Тактовая частота • SSE, AVX 2005 – 2.5-3.6 Ghz – 2005: 2 операции на такт 2012 – 1.8-3.5 Ghz – 2012: 16 операций на такт • Инструкции/такт после Intel Core2 => роста очень медленный
  • 3. Локальная параллельность • Только в хотспотах – Замена обычных циклов - параллельными – Замена обычных команд – векторными (SIMD: SSE, AVX) • Сопутствующие изменения – Редизайн/рефакторинг структур данных – Изменения в алгоритмах
  • 5. Схема работы • Fork/join на месте длинных циклов • Накладные расходы – n*1-10µsec на каждый поток • Методы реализации – Полуавтоматически: OpenMP – Вручную: threading-библиотеки
  • 6. OpenMP • Простой синтаксис: #pragma в последовательном коде #pragma omp parallel for for(i=0;i<N;i++) a[i] = b[i]+c[i]; • Возможности: reduction, atomics, critical sections, режим доступа к переменным: sum=0.0; #pragma omp parallel for reduction(+:sum) for(i=0;i<N;i++) sum+=vector[i];
  • 7. OpenMP • Чужеродность для С++ – Нет поддержки exceptions • Не все компиляторы поддерживают • Бывают ошибки в рантайме (или компиляторе) • Альтернатива: Cilk Plus (Intel C++, gcc 4.8 branch)
  • 8. Параллельные библиотеки Intel TBB: суммирование вектора
  • 9. Итого 1. Это работает ! 2. Эффективность: – Обычно 75-85% (3-3.5x speedup на 4-core) – >90% для «гигабайт» данных 3. Дополнительный код: – 1-20 строк на каждую точку оптимизации
  • 11. SSE/AVX: что это такое? • SSE: одновременные операции над 128-битными векторами addps xmm0,xmm1 означает: for(i=0;i<4;i++) xmm0[i]+=xmm1[i]; • AVX: вектор 128 или 256 бит, 3-адресность: vaddps ymm0,ymm1,ymm2 означает: for(i=0;i<8;i++) ymm0[i]=ymm1[i]+ymm2[i];
  • 12. X86: много сортов SIMD • Под что код делать будем? – 6 версий SSE – 2 версии AVX • Чем новее версия – Тем больше вкусных команд – И тем уже поддержка
  • 13. SSE/AVX: что умеет Что есть: Что есть: • Команды • 16 (8) регистров – Load/store • Типы данных – Арифметика – Целые: 8, 16, 32, 64 бит – Сравнения, min, max – Плавающие: 32, 64 – Конверсия типов Чего нет: – Битовые операции • Flow control – Перестановка элементов вектора • Scatter/gather – Dot Product, CRC32, AES, S TRCMP
  • 14. SSE/AVX: упаковка данных Стандартный ООП-вариант Structure of Arrays (SoA) Array Of Structures (AoS) class foo_vector { class foo { vector<float> x,y,z; float x,y,z; }; void calc_z(){z=A*x+B*y;} foo_vector::calc_z() }; for(..) z[i]=A*x[i]+B*y[i]; vector<foo> fv(..); for(…..) fv[i].calc_z(); calc_z() – хорошо векторизуется: • for(..)calc_z() – плохо – 2 чтения векторизуется: – 3 оп. арифметики – 4-8 чтений – 1 запись – 3 оп. арифметики – 4 записи
  • 15. SSE: выравнивание • До Intel Core-i7: – aligned (16 байт) load/store – сильно быстрее (~4 раза для Core2Duo) • Начиная с Core-i7: – Почти нет разницы (<10%)
  • 16. С/C++: выравнивание • Переменные и поля в структурах: Gcc: int bar[64] __attribute_((aligned(16))); MSVC:__declspec(align(16)) float baz[32]; • Простые аллокации: – MSVC: _aligned_malloc(size, align)/_aligned_free() – Gcc: _mm_malloc(size, align)/_mm_free() • STL: выравнивающий аллокатор: std::vector<T, AlignmentAllocator<T, 16> > foo; Все элементы вектора выровнены на 16: class __attribute__ ((aligned (16))) Foo { __attribute__ ((aligned (16))) float bar[4]; }; std::vector<Foo, AlignmentAllocator<Foo, 16> > baz; У последнего примера – проблемы с Microsoft STL (починено в VS2012)
  • 17. Откуда берется SSE/AVX-код? 1. Генерирует C/C++ компилятор (автоматическая векторизация) 2. Пишется руками – макросы компилятора (compiler intrinsics) – ассемблер
  • 18. Compiler intrinsics: нудную работу должен делать компилятор Стандартные типы данных Макросы для команд __m128 __m128 => SSE-регистр _mm_add_ps(__m128,__m128) (float[4] или int16[8] или еще 6 вариантов) => addps (или vaddps) Компилятор: __m128d => double[2] • Распределяет регистры • Подставляет адреса C- Типы AVX-256: переменных __m256 => float[8] • Генерирует код под целевую архитектуру (SSE, AVX) __m256d => double[4] • Может переупорядочить команды
  • 19. Ручной код: compiler intrinsics C: 277 Mpix/sec (8.8 Gb/sec) SSE/AVX: 584 Mpix/sec (18.6 Gb/s) компилятор частично векторизовал
  • 20. SIMD: Итого 1. Это не больно! 2. Выигрыш в 2-4 раза - запросто 3. Трудный старт 4. Где брать информацию: – Intel Software Developers Manual, Vol 2A & 2B – MSDN: руководство по Visual Studio, много мелких примеров по _mm-макросам – Собирать по крупицам… 
  • 22. Intel SPMD Program Compiler (ISPC) • SPMD – Single Program, Multiple Data • Метафора: «пишем программу для одного SIMD- элемента, компилятор расширит на весь вектор» • x86: SSE2, SSE4, AVX, AVX2, Xeon Phi • Поддерживается Intel: BSD-license, opensource, http://ispc.github.com
  • 23. ISPC: пример и синтаксис Сложение векторов Расширение C: • uniform – разделяемая копия переменной на все параллельные/SIMD потоки varying – приватная копия • foreach/foreach_tiled – SIMD- цикл (тело цикла векторизуется) запускается • launch - запуск задачи • Встроенные переменные: programIndex – номер SIMD- lane programCount – ширина SIMD taskIndex – номер задачи • Далее – см. документацию
  • 26. OpenCL • Стандарт для «гетерогенных вычислений» • Платформы: CPU/GPU • Особенности – Компиляция на лету – Двойная буферизация – Отдельный внешний рантайм – Громоздкий API • Применение – Для больших объемов вычислений – Если планируется переход на GPU-расчеты
  • 27. Позитив • Ускорение в 10-15 раз – достижимо • Вероятно, потребуется рефакторинг Но только один раз: – Параллельный код неплохо масштабируется – Рефакторинг для CPU => годится для GPU • Но лучше – сразу писать эффективно, помня о грядущей паралельности
  • 28. Презентация (со ссылками) доступна: www.slideshare.net/AlexTutubalin Я иногда пишу на эти темы: blog.lexa.ru/tags/sse СПАСИБО ЗА ВНИМАНИЕ! ВОПРОСЫ?
  • 30. Bandwidth vs Latency Bandwidth Latency RAM,1980 13 MB/s 225 ns • Случайный доступ - RAM, 2000 1600 MB/s 52 ns (~125x) (~4.5x) медленный RAM, 2012 12800 MB/s 35ns – «Память – это новый диск» (~1000x) (~6.5x) – «Диск – это новая лента» HDD, 1980 0.6 MB/s 48 ms HDD, 2000 86 MB/s 5.7 ms • У CPU – то же самое!! (~150x) (~8.5x) • Кэши – немного спасают HDD,2012 300 MB/s ~5 ms (~500x) (~10x) • LAN – приятное 10 Mbit 1 MB/s 3000 µsec исключение из общего Ethernet правила 56Gbit ~5000 MB/s 0.7 µsec Infiniband (5000x) (~4300x)
  • 31. BW/Latency: решения • Нужно не зависеть от Latency: – Последовательный код – Нет зависимости по данным – Последовательный доступ к памяти (и диску) – Prefetch в кэши • А любая случайность – зло: – Обращение по указателю – Синхронизация (!) – Не предсказанный условный переход – Случайный disk seek
  • 32. Векторизация С/C++: алиасинг Сложение двух векторов: void sum_vec(float *s1,float *s2, float *d, int N){ for(int i=0;i<N;i++) d[i] = s1[i]+ s2[i]; } Вызов: float A[SZ]; sum_vec(A,A+1,A+2,SZ-2); Решение: restrict (C99), __restrict__(gcc C++), __restrict (MSVC): void sum_vec(float * __restrict__ s1, float* __restrict__ s2, float* __restrict__ d…. Но: • Алиасинг бывает и на this • В библиотечных классах – может не быть указан restrict
  • 33. Векторизация в C++ компиляторах • «Обычный код» (после базовых правок выравнивания и алиасинга): – Личный опыт: ускорения «в разы» компилятор не дает, нужно вручную. – Чужой опыт: «An Evaluation of Vectorizing Compilers» (2011) http://polaris.cs.uiuc.edu/~garzaran/doc/pact11.pdf Для кода Media Bench II получили: • Intel C++/GCC: среднее ускорение 1.2 раза. • Ручной ассемблерный код: ускорение 2.7 раза. • Нужны серьезные правки кода, см. например Program Optimization Trough Loop Vectorization https://wiki.engr.illinois.edu/download/attachments/114 688007/9-Vectorization.pdf
  • 34. Модификация кода для успешной векторизации Не векторизуется Векторизуется for(i=0;i<LEN;i++){ for(i=0;i<LEN;i++){ sum = 0.0; sum[i] = 0.0; for(j=0;j<LEN;j++) for(j=0;j<LEN;j++) sum+=A[j][i]; sum[i]+=A[j][i]; B[i] = sum; B[i] = sum[i]; } }
  • 36. OpenCL: корни в GPGPU • Много отдельных потоков (Work Items) • Объединенных в блоки с быстрой общей памятью (Work Groups) • Блоков много, порядок исполнения не определен • Общая глобальная (медленная) память

Notas do Editor

  1. + альтернативы
  2. TBB,QtConcurrent, boost::mapreduce
  3. 20м надо 16
  4. 20m
  5. 9 минут
  6. 25м
  7. 20 минут?
  8. 25m