SlideShare ist ein Scribd-Unternehmen logo
1 von 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, STRCMP
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: сложение векторов

Weitere ähnliche Inhalte

Was ist angesagt?

Лекция 9. Программирование GPU
Лекция 9. Программирование GPUЛекция 9. Программирование GPU
Лекция 9. Программирование GPUMikhail Kurnosov
 
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 4. Векторизация кода (Code vectorization: SSE, AVX)Mikhail Kurnosov
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Mikhail Kurnosov
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSUlarhat
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Mikhail Kurnosov
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandraodnoklassniki.ru
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Mikhail Kurnosov
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Mikhail Kurnosov
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...Mikhail Kurnosov
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Mikhail Kurnosov
 
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Unigine Corp.
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Mikhail Kurnosov
 
Лекция 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
 
Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Ontico
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)Smolensk Computer Science Club
 
Atomics, CAS and Nonblocking algorithms
Atomics, CAS and Nonblocking algorithmsAtomics, CAS and Nonblocking algorithms
Atomics, CAS and Nonblocking algorithmsAlexey Fyodorov
 
Модель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексМодель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексYandex
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...Mikhail Kurnosov
 

Was ist angesagt? (20)

Лекция 9. Программирование GPU
Лекция 9. Программирование GPUЛекция 9. Программирование GPU
Лекция 9. Программирование GPU
 
Лекция 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)
 
За гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на CassandraЗа гранью NoSQL: NewSQL на Cassandra
За гранью NoSQL: NewSQL на Cassandra
 
Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
 
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
 
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
Как впихнуть утро в сосновом лесу в 4 килобайта. Иван Авдеев. UNIGINE Open Ai...
 
введение в Gpu
введение в Gpuвведение в Gpu
введение в Gpu
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
 
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
Лекция 3: Векторизация кода (Code vectorization, SIMD, SSE, AVX)
 
Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Atomics, CAS and Nonblocking algorithms
Atomics, CAS and Nonblocking algorithmsAtomics, CAS and Nonblocking algorithms
Atomics, CAS and Nonblocking algorithms
 
Модель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, ЯндексМодель памяти C++ - Андрей Янковский, Яндекс
Модель памяти C++ - Андрей Янковский, Яндекс
 
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
Лекция 5. Основы параллельного программирования (Speedup, Amdahl's law, paral...
 

Ähnlich wie Доклад на Highload-2012

Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Unigine Corp.
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...Yandex
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAMikhail Kurnosov
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2Technopark
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Ontico
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Ontico
 
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
 
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...Cisco Russia
 
Максим Богук. Postgres-XC
Максим Богук. Postgres-XCМаксим Богук. Postgres-XC
Максим Богук. Postgres-XCPostgreSQL-Consulting
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Ontico
 
Пути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияПути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияAndrew Babiy
 
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
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Mikhail Kurnosov
 
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPВебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPFlyElephant
 

Ähnlich wie Доклад на Highload-2012 (20)

Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
CUDA Best Practices (2-3)
CUDA Best Practices (2-3)CUDA Best Practices (2-3)
CUDA Best Practices (2-3)
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
 
Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)Что такое Postgresql (Максим Богук)
Что такое Postgresql (Максим Богук)
 
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
 
Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)
 
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
Виртуализация сетевой инфраструктуры на примере использования IOS-XRv 9000 и ...
 
Максим Богук. Postgres-XC
Максим Богук. Postgres-XCМаксим Богук. Postgres-XC
Максим Богук. Postgres-XC
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...
 
Пути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обученияПути увеличения эффективности реализации алгоритмов машинного обучения
Пути увеличения эффективности реализации алгоритмов машинного обучения
 
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 по сети своими руками
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPВебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
 

Доклад на Highload-2012

  • 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, STRCMP
  • 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) • Блоков много, порядок исполнения не определен • Общая глобальная (медленная) память

Hinweis der Redaktion

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