SlideShare a Scribd company logo
1 of 38
Производительность
Вычислительная мощность
компьютера (производительность
компьютера)  —  это  количественная 
характеристика  скорости  выполнения 
определённых операций на компьютере.
Технически  современный микропроцессор
выполнен  в  виде  одной  сверхбольшой 
интегральной  схемы,  состоящей  из 
нескольких  миллиардов  элементов  —  это 
одна  из  самых  сложных  конструкций, 
созданных человеком. 
1
Закон Мура
Гордон Мур,  один  из  основателей 
компании  Intel,  сформулировал 
получивший  его  имя  закон  в  1965 
году.  Описание  закономерности 
звучит  так:  «Количество 
транзисторов,  размещаемых  на 
кристалле  интегральной  схемы, 
удваивается каждые  12 месяцев». В 
1975 году Мур скорректировал свое 
предсказание, увеличив этот срок до 
двух лет.
2
Закон Мура?
3
Совершенствование архитектуры
Совершенствование процесса выполнения инструкций:
  Совершенствование архитектуры набора команд:
RISC, CISC, MISC, VLIW
  Параллелизм уровня инструкций:
конвейерная архитектура, суперскалярная обработка
  Параллелизм уровня потоков:
многопроцессорные системы, многопоточность, многоядерные 
процессоры
  Параллелизм данных: векторная обработка данных
(векторные процессоры/инструкции)
4
Векторная обработка данных 
Векторный процессор (vector processor) – процессор, 
поддерживающий на уровне системы команд операции для работы с 
одномерными массивами (векторами).
5
Векторный VS Скалярный
Скалярный процессор
for i = 1 to 10 do
IF – Instruction Fetch(next)
ID – Instruction Decode
Load Operand1
Load Operand2
Add Operand1 Operand2
Store Result
end for
Векторный процессор
IF – Instruction Fetch(next)
ID – Instruction Decode
Load Operand1
Load Operand2
Add Operand1 Operand2
Store Result
6
Меньше преобразований адресов
Меньше IF, ID
Меньше конфликтов конвейера, ошибок предсказания 
переходов
Эффективнее доступ к памяти (2 выборки vs 20)
Операция над операндами выполняется параллельно
Уменьшился размер кода
Что такое векторные инструкции
SIMD (single instruction, multiple data — одиночный поток команд,
множественный поток данных) — принцип компьютерных 
вычислений, позволяющий обеспечить параллелизм на уровне 
данных.
7
 Одна инструкция, много данных
 Каждая операция применяется к 
N значений в одном (большом) 
регистре фиксированного 
размера (128, 256, 512 бит)
 Может быть до N раз быстрее 
обычных АЛУ
SIMD-инструкции
Intel x86
 MMX 64 bits float, double
 SSE 128 bits float
 SSE2 128 bits int8, int16, int32, int64,
double
 SSE3, SSSE3
 SSE4a (AMD)
 SSE4.1, SSE4.2
 AVX 256 bits float, double
 AVX2 256 bits int8, int16, int32, int64
 FMA3
 FMA4, XOP (AMD)
 MIC 512 bits float, double, int32, int64
8
PowerPC
 AltiVec 128 bits int8, int16, int32,
int64, float
 Cell SPU & VSX, 128 bits int8,
int16, int32, int64, float, double
 QPX 512 bits double
ARM
 VFP 64 bits float, double
 NEON 64 bits & 128 bits float,
int8, int16, int32, int64
MMX
1997, Intel Pentium MMX
 MMX – набор SIMD-инструкции для обработки целочисленных 
векторов длиной 64 бит
 8 виртуальных регистров mm0 – mm7
 Типы векторов: 
9
 mm# quadword
 8 x char char char char char char char char char
 4 x short int short int short int short int short int
 2 x int int int
SSE
1999, Intel Pentium III
 8 (16 для x64) векторных регистров шириной 128 бит: xmm0 – xmm7
 32-битный (в x86-64 — 64) регистр флагов (MXCSR)
 Инструкции над вещественными числами одинарной точности
 Инструкции явной предвыборки данных, контроля кэширования 
данных
 70 инструкций: команды пересылки, арифметические команды,
команды сравнения, преобразования типов, побитовые операции
 Типы векторов: 
 4 x float
10
SSE2
2001, Pentium 4, IA32, x86-64 (Intel 64, 2004)
 16 векторных регистров шириной 128 бит: xmm0 – xmm15
 Добавлено 144 инструкции к 70 инструкциям SSE
 Продолжение SSE работает с вещественными числами
 SSE2 включает в себя ряд команд управления кэшем
 Типы векторов:
 16 x char
 8 x short int
 4 x float или int
 2 x double
 1 x 128-bit int
11
SSE3/4
Intel SSE3: 2003, Pentium 4 Prescott, IA32, x86-64 (Intel 64, 2004)
 Добавлено 13 новых инструкции к инструкциям SSE2
 Возможность горизонтальной работы с регистрами – команды
сложения и вычитания нескольких значений, хранящихся в одном
регистре
12
Intel SSE4: 2006, Intel Core, AMD
Bulldozer
 Добавлено 54 новых инструкций
 SSE 4.1 – 47
 SSE 4.2 – 7
AVX
2008, Intel Sandy Bridge (2011), AMD Bulldozer (2011)
 Добавлено 13 новых инструкции к инструкциям SSE2
 Размер векторов увеличен до 256 бит
 Векторные регистры переименованы: ymm0 – ymm15
 Регистры xmm# – это младшие 128 бит регистров ymm#
 Трехоперандный синтаксис AVX-инструкций: С = A + B
 Использование ymm регистров требует поддержки со стороны операционной системы (для
сохранения регистров при переключении контекстов)
 Linux ядра >= 2.6.30
 Apple OS X 10.6.8
 Windows 7 SP 1
 Поддержка компиляторами:
 GCC 4.6
 Intel C++ Compiler 11.1
 Microsoft Visual Studio 2010
 Open64 4.5.1
13
Эволюция SIMD
14
Эволюция SIMD
15
MMX
(1997)
MM0-MM7,
64-битные
регистры
SSE
(1999)
XMM0-XMM7,
128-битные
регистры
SSE2
(2001)
XMM0-
XMM15, 128-
битные
регистры
SSE3
(2004)
SSE4
(2007)
AVX (2011)
YMM0-YMM15,
256-битные
регистры
AVX2
(2014)
AVX512
(2015)
ZMM0-ZMM31,
512-битные
регистры
Инструкции SSE/AVX
16
Скалярные SSE/AVX-инструкции
17
Скалярные SSE-инструкции (scalar instruction) – в операции участвуют
только младшие элементы данных (скаляры) в векторных
регистрах/памяти
Векторные SSE/AVX-инструкции
18
SSE-инструкция над упакованными векторами (packed instruction) –
в операции участвуют все элементы векторных регистров/памяти
Инструкции
19
 Операции копирования данных (mem-reg/reg-mem/reg-reg)
 Scalar: MOVSS
 Packed: MOVAPS, MOVUPS, MOVLPS, MOVHPS,MOVLHPS, MOVHLPS
 Арифметические операции
 Scalar: ADDSS, SUBSS, MULSS, DIVSS, RCPSS,
SQRTSS, MAXSS, MINSS, RSQRTSS
 Packed: ADDPS, SUBPS, MULPS, DIVPS, RCPPS,
SQRTPS, MAXPS, MINPS, RSQRTPS
 Операции сравнения
 Scalar: CMPSS, COMISS, UCOMISS
 Pacled: CMPPS
 Поразрядные логические операции
 Packed: ANDPS, ORPS, XORPS, ANDNPS
 ......
Математика Скалярный
оператор
Векторный
оператор
X = X + Y addss addps
X = X – Y subss subps
X = X × Y mulss mulps
X = X / Y divss divps
X = rcpss rcpps
X = sqrtss sqrtps
X = rsqrtss rsqrtps
X = max(X, Y) maxss maxps
X = min(X, Y) minss minps
Математика Скалярный
оператор
Векторный
оператор
X = X + Y addss addps
X = X – Y subss subps
X = X × Y mulss mulps
X = X / Y divss divps
rcpss rcpps
sqrtss sqrtps
rsqrtss rsqrtps
X = max(X, Y) maxss maxps
X = min(X, Y) minss minps
Где искать?
20
https://software.intel.com/sites/landingpage/IntrinsicsGuide/
http://x86.renejeschke.de/
Как использовать?
21
[BITS 64]
DEFAULT REL
GLOBAL _main
EXTERN ExitProcess
EXTERN GetStdHandle
EXTERN WriteFile
SECTION .text
_main:
;align stack to 16 bytes for Win64 calls
and rsp, -10h
;give room to Win64 API
;calls that don't take stack params
sub rsp, 020h
mov rcx, -0Bh ;STD_OUTPUT_HANDLE
call GetStdHandle
movdqu xmm0, [arr]
movdqu xmm1, [message]
paddb xmm0, xmm1
movdqa [message], xmm0
mov rcx, rax
mov rdx, message
mov r8, msglen
xor r9, r9
push r9
sub rsp, 20h ;Give Win64 API calls room
call WriteFile
add rsp, 28h ;Restore Stack Pointer
mov rcx, 0
call ExitProcess
xor rax, rax
ret
SECTION .data
arr db 50,68,62,-9,36,26,30,21,-15,58,68,-15,52,64,64,61
message db '////////////////', 10
msglen equ $-message
Компилируем и запускаем
22
Компилируем и запускаем
23
Сложно? Да!
Как проще?
24
Ассемблер Ассемблерные
вставки
Встроенные
функции
компилятора
(Intrinsic)
Специальные
классы
Автоматическая
векторизация
компилятора
Сложно
Лучшая управляемость
(полный контроль у разработчика)
Легко
(нет контроля у разработчика,
надеемся на компилятор)
SIMD в высокоуровневых языках
25
Intrinsic в C++
26
 Intrinsics – набор встроенных функций и типов данных, поддерживаемых
компилятором, для предоставления высокоуровневого доступа к SSE-инструкциям
 Компилятор самостоятельно распределяет XMM/YMM регистры, принимает решение
о способе загрузки данных из памяти (проверяет выравнен адрес или нет) и т.п.
 Заголовочные файлы
#include <mmintrin.h> /* MMX */
#include <xmmintrin.h> /* SSE, нужен также mmintrin.h */
#include <emmintrin.h> /* SSE2, нужен также xmmintrin.h */
#include <pmmintrin.h> /* SSE3, нужен также emmintrin.h */
#include <smmintrin.h> /* SSE4.1 */
#include <nmmintrin.h> /* SSE4.2 */
#include <immintrin.h> /* AVX */
__m128 float[4]
__m128d double[2]
__m128i char[16], short int[8], int[4], uint64_t [2]
 Типы встроенных данных
Intrinsic в деле
27
#include "iostream"
#include "xmmintrin.h"
int main()
{
const auto N = 8;
alignas(16) float a[] = { 41982.0, 81.5091, 3.14, 42.666,
54776.45, 342.4556, 6756.2344, 4563.789 };
alignas(16) float b[] = { 85989.111, 156.5091, 3.14, 42.666,
1006.45, 9999.4546, 0.2344, 7893.789 };
__m128* a_simd = reinterpret_cast<__m128*>(a);
__m128* b_simd = reinterpret_cast<__m128*>(b);
auto size = sizeof(float);
void *ptr = _aligned_malloc(N * size, 32);
float* c = reinterpret_cast<float*>(ptr);
for (size_t i = 0; i < N/2; i++, a_simd++, b_simd++, c += 4)
_mm_store_ps(c, _mm_add_ps(*a_simd, *b_simd));
c -= N;
std::cout.precision(10);
for (size_t i = 0; i < N; i++)
std::cout << c[i] << std::endl;
_aligned_free(ptr);
system("PAUSE");
return 0;
}
SIMD в C#
28
На данный момент поддержка этой технологии в .NET представлена в пространстве имен
System.Numerics.Vectors и представляет собой библиотеку векторных типов, которые могут
использовать преимущества аппаратного ускорения SIMD. Она содержит следующие типы:
 Vector — коллекцию статических удобных методов для работы с универсальными
векторами
 Matrix3x2 — представляет матрицу 3х2
 Matrix4х4 — представляет матрицу 4х4
 Plane — представляет трехмерную плоскость
 Quaternion — представляет вектор, используемый для кодирования трехмерных
физических поворотов
 Vector<(Of <(<'T>)>)> представляет вектор указанного числового типа, который подходит
для низкоуровневой оптимизации параллельных алгоритмов
 Vector2 — представляет вектор с двумя значениями одинарной точности с плавающей
запятой
 Vector3 — представляет вектор с тремя значениями одинарной точности с плавающей
запятой
 Vector4 — представляет вектор с четырьмя значениями одинарной точности с плавающей
запятой
System.Numerics.Vectors
29
using System;
using System.Numerics;
static void Main(string[] args)
{
const Int32 N = 8;
Single[] a = { 41982.0F, 81.5091F, 3.14F, 42.666F, 54776.45F, 342.4556F, 6756.2344F, 4563.789F };
Single[] b = { 85989.111F, 156.5091F, 3.14F, 42.666F, 1006.45F, 9999.4546F, 0.2344F, 7893.789F };
Single[] c = new Single[N];
for (int i = 0; i < N; i += Vector<Single>.Count)
{
var aSimd = new Vector<Single>(a, i);
var bSimd = new Vector<Single>(b, i);
Vector<Single> cSimd = aSimd + bSimd;
cSimd.CopyTo(c, i);
}
for (int i = 0; i < a.Length; i++)
Console.WriteLine(c[i]);
Console.ReadKey();
}
Простой пример
30
[Benchmark(Description = "VectorSum")]
public int VectorSum()
{
var vSize = Vector<int>.Count;
for (int i = 0; i < c.Length; i += vSize)
{
var aa = new Vector<int>(a, i);
var bb = new Vector<int>(b, i);
aa += bb;
aa.CopyTo(c, i);
}
return c[0];
}
[Benchmark(Description = "SimpleSum", Baseline = true)]
public int SimpleSum()
{
for (int i = 0; i < c.Length; i++)
c[i] = a[i] + b[i];
return c[0];
}
Method Platform Jit Median StdDev Scaled
SimpleSum X64 LegacyJit 2.3991 us 0.0818 us 1
SimpleSum X64 RyuJit 4.9439 us 0.4746 us 2.06
SimpleSum X86 LegacyJit 4.0082 us 0.3158 us 1.66
VectorSum X64 LegacyJit 51.9921 us 4.5165 us 21.67https://github.com/PerfDotNet/BenchmarkDotNet/ - benchmark for .NET
Почему так????
31
var aa = new Vector<int>(a, i);
014F35A6 mov edx,dword ptr [esi+4]
014F35A9 push edi
014F35AA lea ecx,[ebp-1Ch]
014F35AD call dword ptr ds:[552419Ch]
var bb = new Vector<int>(b, i);
014F35B3 mov edx,dword ptr [esi+8]
014F35B6 push edi
014F35B7 lea ecx,[ebp-2Ch]
014F35BA call dword ptr ds:[552419Ch]
aa += bb;
014F35C0 lea eax,[ebp-1Ch]
014F35C3 sub esp,10h
014F35C6 movq xmm0,mmword ptr [eax]
014F35CA movq mmword ptr [esp],xmm0
014F35CF movq xmm0,mmword ptr [eax+8]
014F35D4 movq mmword ptr [esp+8],xmm0
014F35DA lea eax,[ebp-2Ch]
014F35DD sub esp,10h
014F35E0 movq xmm0,mmword ptr [eax]
014F35E4 movq mmword ptr [esp],xmm0
014F35E9 movq xmm0,mmword ptr [eax+8]
014F35EE movq mmword ptr [esp+8],xmm0
014F35F4 lea ecx,[ebp-1Ch]
014F35F7 call dword ptr ds:[55241BCh]
aa.CopyTo(c, i);
014F35FD mov edx,dword ptr [esi+0Ch]
014F3600 push edi
014F3601 lea ecx,[ebp-1Ch]
014F3604 call dword ptr ds:[55241B0h]
var aa = new Vector<int>(a, i);
00007FFD3BDB5370 mov rdx,qword ptr [rcx+8]
00007FFD3BDB5374 mov r8d,dword ptr [rdx+8]
00007FFD3BDB5378 cmp eax,r8d
00007FFD3BDB537B jae 00007FFD3BDB53EE
00007FFD3BDB537D mov r8d,dword ptr [rdx+8]
00007FFD3BDB5381 lea r9d,[rax+7]
00007FFD3BDB5385 cmp r9d,r8d
00007FFD3BDB5388 jae 00007FFD3BDB53EE
00007FFD3BDB538A vmovupd ymm0,ymmword ptr [rdx+rax*4+10h]
var bb = new Vector<int>(b, i);
00007FFD3BDB5391 mov rdx,qword ptr [rcx+10h]
var bb = new Vector<int>(b, i);
00007FFD3BDB5395 mov r8d,dword ptr [rdx+8]
00007FFD3BDB5399 cmp eax,r8d
00007FFD3BDB539C jae 00007FFD3BDB53EE
00007FFD3BDB539E mov r8d,dword ptr [rdx+8]
00007FFD3BDB53A2 cmp r9d,r8d
00007FFD3BDB53A5 jae 00007FFD3BDB53EE
00007FFD3BDB53A7 vmovupd ymm1,ymmword ptr [rdx+rax*4+10h]
aa += bb;
00007FFD3BDB53AE vpaddd ymm0,ymm0,ymm1
aa.CopyTo(c, i);
00007FFD3BDB53B3 mov rdx,qword ptr [rcx+18h]
00007FFD3BDB53B7 mov r8d,dword ptr [rdx+8]
00007FFD3BDB53BB cmp eax,r8d
00007FFD3BDB53BE jae 00007FFD3BDB53F3
00007FFD3BDB53C0 mov r8d,dword ptr [rdx+8]
00007FFD3BDB53C4 cmp r9d,r8d
00007FFD3BDB53C7 jae 00007FFD3BDB53F8
00007FFD3BDB53C9 vmovupd ymmword ptr [rdx+rax*4+10h],ymm0
x64 x86
А на практике ???
32
Свёртка (в случае изображения) — это операция вычисления нового значения
заданного пикселя, при которой учитываются значения окружающих его соседних
пикселей.
Пример использования свертки
33
 Фильтрация
Свёртка — очень полезная и распространённая операция, лежащая в основе различных
фильтров (размытие, повышение резкости, нахождение краёв, подавление шумов).
Фильтр улучшения четкостиФильтр размытие
Пример использования свертки
34
 Сверточные нейронные сети
Имеется матрица на входе
(картинка) и есть ядро свертки
которое состоит из весов (эти веса в
процессе обучения сверточной
нейронной сети настраиваются).
Ядро построено таким образом, что
графически кодирует какой-либо
один признак, например, наличие
наклонной линии под
определенным углом.
Тогда следующий слой, получившийся в результате операции свёртки такой матрицей
весов, показывает наличие данной наклонной линии в обрабатываемом слое и её
координаты, формируя так называемую карту признаков (англ. feature map).
Реализация операции свертки
35
unsafe public static int[][] Convolution(int[][] img, int[,]
filter)
{
....
var vSize = Vector<int>.Count;
for (int i = 0; i < resHeight; ++i) {
res[i] = new int[resWidth];
fixed (int* resP = res[i], filterP = filter) {
for (int j = 0; j < resWidth; j += vSize) {
var kernel = Vector<int>.Zero;
for (int fi = 0, imgI = i, filterI = 0;
fi < filterHeight; ++fi, ++imgI, filterI += filterWidth)
for (int fj = 0; fj < filterWidth; ++fj) {
var imgV = new Vector<int>(img[imgI], j + fj);
var filterV = new Vector<int>(filterP[filterI + fj]);
kernel += imgV * filterV;
}
kernel.CopyTo(res[i], j);
}
}
}
return res;
}
public static int[][] Convolution(int[][] img, int[,] filter)
{
....
for (int i = 0; i < resHeight; ++i) {
res[i] = new int[resWidth];
for (int j = 0; j < resWidth; ++j) {
var kernel = 0;
for (int fi = 0, imgI = i; fi < filterHeight; ++fi, ++imgI)
for (int fj = 0; fj < filterWidth; ++fj)
kernel += img[imgI][j+fj] * filter[fi, fj];
}
res[i][j] = kernel;
}
}
return res;
}
4 строки – unsafe оптимизация работы с массивом
6 строк – векторизация
Benchmark
36
Method Platform Jit Median Scaled
SimpleJagged X86 LegacyJit 93.9177 ms 1
VectorJagged X86 LegacyJit 251.0950 ms 2.67
SimpleJagged X64 LegacyJit 103.8635 ms 1
VectorJagged X64 LegacyJit 341.3388 ms 3.28
SimpleJagged X64 RyuJit 96.0608 ms 1
VectorJagged X64 RyuJit 16.5649 ms 0.17
В итоге
37
Что мы имеем:
 Во многих случаях векторизация дает увеличение производительности (размер вектора,
реализация)
 Сложные алгоритмы потребуют изобретательность, но без этого никуда
 System.Numerics.Vectors в настоящее время обхватывает только часть simd-инструкций.
Для более серьезного подхода потребуется С++
 Есть множество других способов помимо векторизации: правильное использование кэша,
многопоточность, грамотная работа с памятью(чтобы сборщик мусора не потел) и т.д.
SIMD инструкции это один из способов выжать производительность, но не единственный.
Источник
параллелизма
Ускорение Усилие программиста Популярность
Множество ядер 2х-128х Умеренное Высокая
Множество машин 1х-Бесконечность Умеренно-Высокое Высокая
Векторизация 2х-8х Умеренно-Высокое Низкая
Графические адаптеры 128х-2048х Высокое Низкая
Спасибо за внимание =)
Вопросы?

More Related Content

What's hot

Лекция 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
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...Mikhail Kurnosov
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAMikhail Kurnosov
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Mikhail Kurnosov
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSUlarhat
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Mikhail Kurnosov
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркингаAndrey Akinshin
 
Как мы храним 75 млн пользователей (Денис Бирюков)
Как мы храним 75 млн пользователей  (Денис Бирюков)Как мы храним 75 млн пользователей  (Денис Бирюков)
Как мы храним 75 млн пользователей (Денис Бирюков)Ontico
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...a15464321646213
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Mikhail Kurnosov
 
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработк...Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработк...
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...Ontico
 
Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Mikhail Kurnosov
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Mikhail Kurnosov
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)Smolensk Computer Science Club
 
Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2PyNSK
 
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ontico
 
Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1PyNSK
 

What's hot (20)

Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDAЛекция 11: Программирование графических процессоров на NVIDIA CUDA
Лекция 11: Программирование графических процессоров на NVIDIA CUDA
 
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
Лекция 3. Векторизация кода (Code vectorization: SSE, AVX)
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSU
 
Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)Семинар 8. Параллельное программирование на MPI (часть 1)
Семинар 8. Параллельное программирование на MPI (часть 1)
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркинга
 
Как мы храним 75 млн пользователей (Денис Бирюков)
Как мы храним 75 млн пользователей  (Денис Бирюков)Как мы храним 75 млн пользователей  (Денис Бирюков)
Как мы храним 75 млн пользователей (Денис Бирюков)
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
lecture-monitoring and performance tuning of the computer
lecture-monitoring and performance tuning of the computerlecture-monitoring and performance tuning of the computer
lecture-monitoring and performance tuning of the computer
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработк...Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработк...
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
 
Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)Лекция 10. Биномиальные кучи (Binomial heaps)
Лекция 10. Биномиальные кучи (Binomial heaps)
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2
 
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
 
Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1
 

Viewers also liked

Introduction to X3D
Introduction to X3DIntroduction to X3D
Introduction to X3DAhmed Gad
 
Jedálny lístok 11.2.2013 do 15.2. 2013 papuča
Jedálny lístok 11.2.2013 do 15.2. 2013 papučaJedálny lístok 11.2.2013 do 15.2. 2013 papuča
Jedálny lístok 11.2.2013 do 15.2. 2013 papučamasolapin
 
Ortografía puntual
Ortografía puntualOrtografía puntual
Ortografía puntualPPUU
 
RX US Brand portfolio
RX US Brand portfolio RX US Brand portfolio
RX US Brand portfolio Jdepotter
 
Computing Homework 1234
Computing Homework 1234Computing Homework 1234
Computing Homework 1234FrerixD
 
Recorrido fotográfico por las expos - 01
Recorrido fotográfico por las expos - 01Recorrido fotográfico por las expos - 01
Recorrido fotográfico por las expos - 01IES JR Project
 
Album cover
Album coverAlbum cover
Album coverhibah24
 
Coldcalling tips using james bond
Coldcalling tips using james bond Coldcalling tips using james bond
Coldcalling tips using james bond Tjorven Denorme
 
Q’ magazine reader profile
Q’ magazine reader profileQ’ magazine reader profile
Q’ magazine reader profileSophie Rudd
 

Viewers also liked (13)

Archivo
ArchivoArchivo
Archivo
 
Introduction to X3D
Introduction to X3DIntroduction to X3D
Introduction to X3D
 
Jedálny lístok 11.2.2013 do 15.2. 2013 papuča
Jedálny lístok 11.2.2013 do 15.2. 2013 papučaJedálny lístok 11.2.2013 do 15.2. 2013 papuča
Jedálny lístok 11.2.2013 do 15.2. 2013 papuča
 
Mamita2
Mamita2Mamita2
Mamita2
 
Ortografía puntual
Ortografía puntualOrtografía puntual
Ortografía puntual
 
RX US Brand portfolio
RX US Brand portfolio RX US Brand portfolio
RX US Brand portfolio
 
Minitutorial
MinitutorialMinitutorial
Minitutorial
 
Computing Homework 1234
Computing Homework 1234Computing Homework 1234
Computing Homework 1234
 
Ceros info graphic
Ceros info graphicCeros info graphic
Ceros info graphic
 
Recorrido fotográfico por las expos - 01
Recorrido fotográfico por las expos - 01Recorrido fotográfico por las expos - 01
Recorrido fotográfico por las expos - 01
 
Album cover
Album coverAlbum cover
Album cover
 
Coldcalling tips using james bond
Coldcalling tips using james bond Coldcalling tips using james bond
Coldcalling tips using james bond
 
Q’ magazine reader profile
Q’ magazine reader profileQ’ magazine reader profile
Q’ magazine reader profile
 

Similar to Simd

Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Mikhail Kurnosov
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности PythonPyNSK
 
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOM
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOMYuriy Sherstyuk - Algorithms in Front End: from V8 to VDOM
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOMOdessaJS Conf
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Mikhail Kurnosov
 
025
025025
025JIuc
 
40
4040
40JIuc
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Alex Tutubalin
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonovComputer Science Club
 
Лекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusЛекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusMikhail Kurnosov
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийOOO "Program Verification Systems"
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...Yandex
 
TMPA-2013 Smirnov
TMPA-2013 SmirnovTMPA-2013 Smirnov
TMPA-2013 SmirnovIosif Itkin
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2Technopark
 
тест по теме микропроцессорные системы
тест по теме микропроцессорные системытест по теме микропроцессорные системы
тест по теме микропроцессорные системыJIuc
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кодаTatyanazaxarova
 
ADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кодаADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кодаAndrey Karpov
 
41
4141
41JIuc
 
Делаем кроссбраузерные тесты поверх Webdriver
Делаем кроссбраузерные тесты поверх WebdriverДелаем кроссбраузерные тесты поверх Webdriver
Делаем кроссбраузерные тесты поверх WebdriverSQALab
 
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryИнтервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryTatyanazaxarova
 

Similar to Simd (20)

Векторизация кода (семинар 1)
Векторизация кода (семинар 1)Векторизация кода (семинар 1)
Векторизация кода (семинар 1)
 
Оптимизация производительности Python
Оптимизация производительности PythonОптимизация производительности Python
Оптимизация производительности Python
 
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOM
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOMYuriy Sherstyuk - Algorithms in Front End: from V8 to VDOM
Yuriy Sherstyuk - Algorithms in Front End: from V8 to VDOM
 
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
 
025
025025
025
 
40
4040
40
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
Лекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusЛекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk Plus
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 
TMPA-2013 Smirnov
TMPA-2013 SmirnovTMPA-2013 Smirnov
TMPA-2013 Smirnov
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
 
тест по теме микропроцессорные системы
тест по теме микропроцессорные системытест по теме микропроцессорные системы
тест по теме микропроцессорные системы
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кода
 
ADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кодаADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кода
 
41
4141
41
 
Делаем кроссбраузерные тесты поверх Webdriver
Делаем кроссбраузерные тесты поверх WebdriverДелаем кроссбраузерные тесты поверх Webdriver
Делаем кроссбраузерные тесты поверх Webdriver
 
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ LibraryИнтервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
Интервью с Анатолием Кузнецовым, автором библиотеки BitMagic C++ Library
 

Simd

  • 1. Производительность Вычислительная мощность компьютера (производительность компьютера)  —  это  количественная  характеристика  скорости  выполнения  определённых операций на компьютере. Технически  современный микропроцессор выполнен  в  виде  одной  сверхбольшой  интегральной  схемы,  состоящей  из  нескольких  миллиардов  элементов  —  это  одна  из  самых  сложных  конструкций,  созданных человеком.  1
  • 2. Закон Мура Гордон Мур,  один  из  основателей  компании  Intel,  сформулировал  получивший  его  имя  закон  в  1965  году.  Описание  закономерности  звучит  так:  «Количество  транзисторов,  размещаемых  на  кристалле  интегральной  схемы,  удваивается каждые  12 месяцев». В  1975 году Мур скорректировал свое  предсказание, увеличив этот срок до  двух лет. 2
  • 4. Совершенствование архитектуры Совершенствование процесса выполнения инструкций:   Совершенствование архитектуры набора команд: RISC, CISC, MISC, VLIW   Параллелизм уровня инструкций: конвейерная архитектура, суперскалярная обработка   Параллелизм уровня потоков: многопроцессорные системы, многопоточность, многоядерные  процессоры   Параллелизм данных: векторная обработка данных (векторные процессоры/инструкции) 4
  • 5. Векторная обработка данных  Векторный процессор (vector processor) – процессор,  поддерживающий на уровне системы команд операции для работы с  одномерными массивами (векторами). 5
  • 6. Векторный VS Скалярный Скалярный процессор for i = 1 to 10 do IF – Instruction Fetch(next) ID – Instruction Decode Load Operand1 Load Operand2 Add Operand1 Operand2 Store Result end for Векторный процессор IF – Instruction Fetch(next) ID – Instruction Decode Load Operand1 Load Operand2 Add Operand1 Operand2 Store Result 6 Меньше преобразований адресов Меньше IF, ID Меньше конфликтов конвейера, ошибок предсказания  переходов Эффективнее доступ к памяти (2 выборки vs 20) Операция над операндами выполняется параллельно Уменьшился размер кода
  • 7. Что такое векторные инструкции SIMD (single instruction, multiple data — одиночный поток команд, множественный поток данных) — принцип компьютерных  вычислений, позволяющий обеспечить параллелизм на уровне  данных. 7  Одна инструкция, много данных  Каждая операция применяется к  N значений в одном (большом)  регистре фиксированного  размера (128, 256, 512 бит)  Может быть до N раз быстрее  обычных АЛУ
  • 8. SIMD-инструкции Intel x86  MMX 64 bits float, double  SSE 128 bits float  SSE2 128 bits int8, int16, int32, int64, double  SSE3, SSSE3  SSE4a (AMD)  SSE4.1, SSE4.2  AVX 256 bits float, double  AVX2 256 bits int8, int16, int32, int64  FMA3  FMA4, XOP (AMD)  MIC 512 bits float, double, int32, int64 8 PowerPC  AltiVec 128 bits int8, int16, int32, int64, float  Cell SPU & VSX, 128 bits int8, int16, int32, int64, float, double  QPX 512 bits double ARM  VFP 64 bits float, double  NEON 64 bits & 128 bits float, int8, int16, int32, int64
  • 9. MMX 1997, Intel Pentium MMX  MMX – набор SIMD-инструкции для обработки целочисленных  векторов длиной 64 бит  8 виртуальных регистров mm0 – mm7  Типы векторов:  9  mm# quadword  8 x char char char char char char char char char  4 x short int short int short int short int short int  2 x int int int
  • 10. SSE 1999, Intel Pentium III  8 (16 для x64) векторных регистров шириной 128 бит: xmm0 – xmm7  32-битный (в x86-64 — 64) регистр флагов (MXCSR)  Инструкции над вещественными числами одинарной точности  Инструкции явной предвыборки данных, контроля кэширования  данных  70 инструкций: команды пересылки, арифметические команды, команды сравнения, преобразования типов, побитовые операции  Типы векторов:   4 x float 10
  • 11. SSE2 2001, Pentium 4, IA32, x86-64 (Intel 64, 2004)  16 векторных регистров шириной 128 бит: xmm0 – xmm15  Добавлено 144 инструкции к 70 инструкциям SSE  Продолжение SSE работает с вещественными числами  SSE2 включает в себя ряд команд управления кэшем  Типы векторов:  16 x char  8 x short int  4 x float или int  2 x double  1 x 128-bit int 11
  • 12. SSE3/4 Intel SSE3: 2003, Pentium 4 Prescott, IA32, x86-64 (Intel 64, 2004)  Добавлено 13 новых инструкции к инструкциям SSE2  Возможность горизонтальной работы с регистрами – команды сложения и вычитания нескольких значений, хранящихся в одном регистре 12 Intel SSE4: 2006, Intel Core, AMD Bulldozer  Добавлено 54 новых инструкций  SSE 4.1 – 47  SSE 4.2 – 7
  • 13. AVX 2008, Intel Sandy Bridge (2011), AMD Bulldozer (2011)  Добавлено 13 новых инструкции к инструкциям SSE2  Размер векторов увеличен до 256 бит  Векторные регистры переименованы: ymm0 – ymm15  Регистры xmm# – это младшие 128 бит регистров ymm#  Трехоперандный синтаксис AVX-инструкций: С = A + B  Использование ymm регистров требует поддержки со стороны операционной системы (для сохранения регистров при переключении контекстов)  Linux ядра >= 2.6.30  Apple OS X 10.6.8  Windows 7 SP 1  Поддержка компиляторами:  GCC 4.6  Intel C++ Compiler 11.1  Microsoft Visual Studio 2010  Open64 4.5.1 13
  • 17. Скалярные SSE/AVX-инструкции 17 Скалярные SSE-инструкции (scalar instruction) – в операции участвуют только младшие элементы данных (скаляры) в векторных регистрах/памяти
  • 18. Векторные SSE/AVX-инструкции 18 SSE-инструкция над упакованными векторами (packed instruction) – в операции участвуют все элементы векторных регистров/памяти
  • 19. Инструкции 19  Операции копирования данных (mem-reg/reg-mem/reg-reg)  Scalar: MOVSS  Packed: MOVAPS, MOVUPS, MOVLPS, MOVHPS,MOVLHPS, MOVHLPS  Арифметические операции  Scalar: ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, MAXSS, MINSS, RSQRTSS  Packed: ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, MAXPS, MINPS, RSQRTPS  Операции сравнения  Scalar: CMPSS, COMISS, UCOMISS  Pacled: CMPPS  Поразрядные логические операции  Packed: ANDPS, ORPS, XORPS, ANDNPS  ...... Математика Скалярный оператор Векторный оператор X = X + Y addss addps X = X – Y subss subps X = X × Y mulss mulps X = X / Y divss divps X = rcpss rcpps X = sqrtss sqrtps X = rsqrtss rsqrtps X = max(X, Y) maxss maxps X = min(X, Y) minss minps Математика Скалярный оператор Векторный оператор X = X + Y addss addps X = X – Y subss subps X = X × Y mulss mulps X = X / Y divss divps rcpss rcpps sqrtss sqrtps rsqrtss rsqrtps X = max(X, Y) maxss maxps X = min(X, Y) minss minps
  • 21. Как использовать? 21 [BITS 64] DEFAULT REL GLOBAL _main EXTERN ExitProcess EXTERN GetStdHandle EXTERN WriteFile SECTION .text _main: ;align stack to 16 bytes for Win64 calls and rsp, -10h ;give room to Win64 API ;calls that don't take stack params sub rsp, 020h mov rcx, -0Bh ;STD_OUTPUT_HANDLE call GetStdHandle movdqu xmm0, [arr] movdqu xmm1, [message] paddb xmm0, xmm1 movdqa [message], xmm0 mov rcx, rax mov rdx, message mov r8, msglen xor r9, r9 push r9 sub rsp, 20h ;Give Win64 API calls room call WriteFile add rsp, 28h ;Restore Stack Pointer mov rcx, 0 call ExitProcess xor rax, rax ret SECTION .data arr db 50,68,62,-9,36,26,30,21,-15,58,68,-15,52,64,64,61 message db '////////////////', 10 msglen equ $-message
  • 24. Как проще? 24 Ассемблер Ассемблерные вставки Встроенные функции компилятора (Intrinsic) Специальные классы Автоматическая векторизация компилятора Сложно Лучшая управляемость (полный контроль у разработчика) Легко (нет контроля у разработчика, надеемся на компилятор)
  • 26. Intrinsic в C++ 26  Intrinsics – набор встроенных функций и типов данных, поддерживаемых компилятором, для предоставления высокоуровневого доступа к SSE-инструкциям  Компилятор самостоятельно распределяет XMM/YMM регистры, принимает решение о способе загрузки данных из памяти (проверяет выравнен адрес или нет) и т.п.  Заголовочные файлы #include <mmintrin.h> /* MMX */ #include <xmmintrin.h> /* SSE, нужен также mmintrin.h */ #include <emmintrin.h> /* SSE2, нужен также xmmintrin.h */ #include <pmmintrin.h> /* SSE3, нужен также emmintrin.h */ #include <smmintrin.h> /* SSE4.1 */ #include <nmmintrin.h> /* SSE4.2 */ #include <immintrin.h> /* AVX */ __m128 float[4] __m128d double[2] __m128i char[16], short int[8], int[4], uint64_t [2]  Типы встроенных данных
  • 27. Intrinsic в деле 27 #include "iostream" #include "xmmintrin.h" int main() { const auto N = 8; alignas(16) float a[] = { 41982.0, 81.5091, 3.14, 42.666, 54776.45, 342.4556, 6756.2344, 4563.789 }; alignas(16) float b[] = { 85989.111, 156.5091, 3.14, 42.666, 1006.45, 9999.4546, 0.2344, 7893.789 }; __m128* a_simd = reinterpret_cast<__m128*>(a); __m128* b_simd = reinterpret_cast<__m128*>(b); auto size = sizeof(float); void *ptr = _aligned_malloc(N * size, 32); float* c = reinterpret_cast<float*>(ptr); for (size_t i = 0; i < N/2; i++, a_simd++, b_simd++, c += 4) _mm_store_ps(c, _mm_add_ps(*a_simd, *b_simd)); c -= N; std::cout.precision(10); for (size_t i = 0; i < N; i++) std::cout << c[i] << std::endl; _aligned_free(ptr); system("PAUSE"); return 0; }
  • 28. SIMD в C# 28 На данный момент поддержка этой технологии в .NET представлена в пространстве имен System.Numerics.Vectors и представляет собой библиотеку векторных типов, которые могут использовать преимущества аппаратного ускорения SIMD. Она содержит следующие типы:  Vector — коллекцию статических удобных методов для работы с универсальными векторами  Matrix3x2 — представляет матрицу 3х2  Matrix4х4 — представляет матрицу 4х4  Plane — представляет трехмерную плоскость  Quaternion — представляет вектор, используемый для кодирования трехмерных физических поворотов  Vector<(Of <(<'T>)>)> представляет вектор указанного числового типа, который подходит для низкоуровневой оптимизации параллельных алгоритмов  Vector2 — представляет вектор с двумя значениями одинарной точности с плавающей запятой  Vector3 — представляет вектор с тремя значениями одинарной точности с плавающей запятой  Vector4 — представляет вектор с четырьмя значениями одинарной точности с плавающей запятой
  • 29. System.Numerics.Vectors 29 using System; using System.Numerics; static void Main(string[] args) { const Int32 N = 8; Single[] a = { 41982.0F, 81.5091F, 3.14F, 42.666F, 54776.45F, 342.4556F, 6756.2344F, 4563.789F }; Single[] b = { 85989.111F, 156.5091F, 3.14F, 42.666F, 1006.45F, 9999.4546F, 0.2344F, 7893.789F }; Single[] c = new Single[N]; for (int i = 0; i < N; i += Vector<Single>.Count) { var aSimd = new Vector<Single>(a, i); var bSimd = new Vector<Single>(b, i); Vector<Single> cSimd = aSimd + bSimd; cSimd.CopyTo(c, i); } for (int i = 0; i < a.Length; i++) Console.WriteLine(c[i]); Console.ReadKey(); }
  • 30. Простой пример 30 [Benchmark(Description = "VectorSum")] public int VectorSum() { var vSize = Vector<int>.Count; for (int i = 0; i < c.Length; i += vSize) { var aa = new Vector<int>(a, i); var bb = new Vector<int>(b, i); aa += bb; aa.CopyTo(c, i); } return c[0]; } [Benchmark(Description = "SimpleSum", Baseline = true)] public int SimpleSum() { for (int i = 0; i < c.Length; i++) c[i] = a[i] + b[i]; return c[0]; } Method Platform Jit Median StdDev Scaled SimpleSum X64 LegacyJit 2.3991 us 0.0818 us 1 SimpleSum X64 RyuJit 4.9439 us 0.4746 us 2.06 SimpleSum X86 LegacyJit 4.0082 us 0.3158 us 1.66 VectorSum X64 LegacyJit 51.9921 us 4.5165 us 21.67https://github.com/PerfDotNet/BenchmarkDotNet/ - benchmark for .NET
  • 31. Почему так???? 31 var aa = new Vector<int>(a, i); 014F35A6 mov edx,dword ptr [esi+4] 014F35A9 push edi 014F35AA lea ecx,[ebp-1Ch] 014F35AD call dword ptr ds:[552419Ch] var bb = new Vector<int>(b, i); 014F35B3 mov edx,dword ptr [esi+8] 014F35B6 push edi 014F35B7 lea ecx,[ebp-2Ch] 014F35BA call dword ptr ds:[552419Ch] aa += bb; 014F35C0 lea eax,[ebp-1Ch] 014F35C3 sub esp,10h 014F35C6 movq xmm0,mmword ptr [eax] 014F35CA movq mmword ptr [esp],xmm0 014F35CF movq xmm0,mmword ptr [eax+8] 014F35D4 movq mmword ptr [esp+8],xmm0 014F35DA lea eax,[ebp-2Ch] 014F35DD sub esp,10h 014F35E0 movq xmm0,mmword ptr [eax] 014F35E4 movq mmword ptr [esp],xmm0 014F35E9 movq xmm0,mmword ptr [eax+8] 014F35EE movq mmword ptr [esp+8],xmm0 014F35F4 lea ecx,[ebp-1Ch] 014F35F7 call dword ptr ds:[55241BCh] aa.CopyTo(c, i); 014F35FD mov edx,dword ptr [esi+0Ch] 014F3600 push edi 014F3601 lea ecx,[ebp-1Ch] 014F3604 call dword ptr ds:[55241B0h] var aa = new Vector<int>(a, i); 00007FFD3BDB5370 mov rdx,qword ptr [rcx+8] 00007FFD3BDB5374 mov r8d,dword ptr [rdx+8] 00007FFD3BDB5378 cmp eax,r8d 00007FFD3BDB537B jae 00007FFD3BDB53EE 00007FFD3BDB537D mov r8d,dword ptr [rdx+8] 00007FFD3BDB5381 lea r9d,[rax+7] 00007FFD3BDB5385 cmp r9d,r8d 00007FFD3BDB5388 jae 00007FFD3BDB53EE 00007FFD3BDB538A vmovupd ymm0,ymmword ptr [rdx+rax*4+10h] var bb = new Vector<int>(b, i); 00007FFD3BDB5391 mov rdx,qword ptr [rcx+10h] var bb = new Vector<int>(b, i); 00007FFD3BDB5395 mov r8d,dword ptr [rdx+8] 00007FFD3BDB5399 cmp eax,r8d 00007FFD3BDB539C jae 00007FFD3BDB53EE 00007FFD3BDB539E mov r8d,dword ptr [rdx+8] 00007FFD3BDB53A2 cmp r9d,r8d 00007FFD3BDB53A5 jae 00007FFD3BDB53EE 00007FFD3BDB53A7 vmovupd ymm1,ymmword ptr [rdx+rax*4+10h] aa += bb; 00007FFD3BDB53AE vpaddd ymm0,ymm0,ymm1 aa.CopyTo(c, i); 00007FFD3BDB53B3 mov rdx,qword ptr [rcx+18h] 00007FFD3BDB53B7 mov r8d,dword ptr [rdx+8] 00007FFD3BDB53BB cmp eax,r8d 00007FFD3BDB53BE jae 00007FFD3BDB53F3 00007FFD3BDB53C0 mov r8d,dword ptr [rdx+8] 00007FFD3BDB53C4 cmp r9d,r8d 00007FFD3BDB53C7 jae 00007FFD3BDB53F8 00007FFD3BDB53C9 vmovupd ymmword ptr [rdx+rax*4+10h],ymm0 x64 x86
  • 32. А на практике ??? 32 Свёртка (в случае изображения) — это операция вычисления нового значения заданного пикселя, при которой учитываются значения окружающих его соседних пикселей.
  • 33. Пример использования свертки 33  Фильтрация Свёртка — очень полезная и распространённая операция, лежащая в основе различных фильтров (размытие, повышение резкости, нахождение краёв, подавление шумов). Фильтр улучшения четкостиФильтр размытие
  • 34. Пример использования свертки 34  Сверточные нейронные сети Имеется матрица на входе (картинка) и есть ядро свертки которое состоит из весов (эти веса в процессе обучения сверточной нейронной сети настраиваются). Ядро построено таким образом, что графически кодирует какой-либо один признак, например, наличие наклонной линии под определенным углом. Тогда следующий слой, получившийся в результате операции свёртки такой матрицей весов, показывает наличие данной наклонной линии в обрабатываемом слое и её координаты, формируя так называемую карту признаков (англ. feature map).
  • 35. Реализация операции свертки 35 unsafe public static int[][] Convolution(int[][] img, int[,] filter) { .... var vSize = Vector<int>.Count; for (int i = 0; i < resHeight; ++i) { res[i] = new int[resWidth]; fixed (int* resP = res[i], filterP = filter) { for (int j = 0; j < resWidth; j += vSize) { var kernel = Vector<int>.Zero; for (int fi = 0, imgI = i, filterI = 0; fi < filterHeight; ++fi, ++imgI, filterI += filterWidth) for (int fj = 0; fj < filterWidth; ++fj) { var imgV = new Vector<int>(img[imgI], j + fj); var filterV = new Vector<int>(filterP[filterI + fj]); kernel += imgV * filterV; } kernel.CopyTo(res[i], j); } } } return res; } public static int[][] Convolution(int[][] img, int[,] filter) { .... for (int i = 0; i < resHeight; ++i) { res[i] = new int[resWidth]; for (int j = 0; j < resWidth; ++j) { var kernel = 0; for (int fi = 0, imgI = i; fi < filterHeight; ++fi, ++imgI) for (int fj = 0; fj < filterWidth; ++fj) kernel += img[imgI][j+fj] * filter[fi, fj]; } res[i][j] = kernel; } } return res; } 4 строки – unsafe оптимизация работы с массивом 6 строк – векторизация
  • 36. Benchmark 36 Method Platform Jit Median Scaled SimpleJagged X86 LegacyJit 93.9177 ms 1 VectorJagged X86 LegacyJit 251.0950 ms 2.67 SimpleJagged X64 LegacyJit 103.8635 ms 1 VectorJagged X64 LegacyJit 341.3388 ms 3.28 SimpleJagged X64 RyuJit 96.0608 ms 1 VectorJagged X64 RyuJit 16.5649 ms 0.17
  • 37. В итоге 37 Что мы имеем:  Во многих случаях векторизация дает увеличение производительности (размер вектора, реализация)  Сложные алгоритмы потребуют изобретательность, но без этого никуда  System.Numerics.Vectors в настоящее время обхватывает только часть simd-инструкций. Для более серьезного подхода потребуется С++  Есть множество других способов помимо векторизации: правильное использование кэша, многопоточность, грамотная работа с памятью(чтобы сборщик мусора не потел) и т.д. SIMD инструкции это один из способов выжать производительность, но не единственный. Источник параллелизма Ускорение Усилие программиста Популярность Множество ядер 2х-128х Умеренное Высокая Множество машин 1х-Бесконечность Умеренно-Высокое Высокая Векторизация 2х-8х Умеренно-Высокое Низкая Графические адаптеры 128х-2048х Высокое Низкая

Editor's Notes

  1. Ключевыми элементами любого микропроцессора являются дискретные переключатели – транзисторы. Блокируя и пропуская электрический ток (включение-выключение), они дают возможность логическим схемам компьютера работать в двух состояниях, то есть в двоичной системе. Размеры транзисторов измеряются в нанометрах. Один нанометр (нм) – это одна миллиардная (10−9) часть метра. На срезе одного человеческого волоса можно разместить более 2000 транзисторных затворов, выполненных по 45-нм производственной технологии. 7
  2. 7
  3. Мировые производители микроэлектроники при совершенствовании техпроцесса изготовления кристаллов все чаще сталкиваются с физическими ограничениями основного материала, используемого для выращивания чипов. Компании уже давно заняты поиском альтернатив кремнию и, по всей видимости, близки к тому, чтобы перейти на новый тип полупроводников. Сложности возникли уже на этапе 14 нм. При уменьшении элементов и расстояния между ними производителям все сложнее получить устойчивые состояния транзисторов (открыт/закрыт) без которого невозможно использовать бинарную логику. Приближаясь к единицам нанометров, сказываются физические ограничения кремния, которые уже нельзя преодолеть, даже используя трехмерную структуру и другие технологические «присадки». «Два последних технологических перехода помогли нам понять, что на сегодняшний день самый реалистичный срок — выпуск новых чипов раз в два с половиной года, а не в два», — заявил руководитель Intel Брайан Крзэнич. 7
  4. Complex instruction set computer — вычисления со сложным набором команд. Процессорная архитектура, основанная на усложнённом наборе команд.  Reduced instruction set computer — вычисления с упрощённым набором команд. Архитектура процессоров, построенная на основе упрощённого набора команд, характеризуется наличием команд фиксированной длины, большого количества регистров, операций типа регистр-регистр, а также отсутствием косвенной адресации. Minimum instruction set computer — вычисления с минимальным набором команд. Very long instruction word — сверхдлинное командное слово. Архитектура процессоров с явно выраженным параллелизмом вычислений, заложенным в систему команд процессора.  Конве́йер — способ организации вычислений, используемый в современных процессорах и контроллерах с целью повышения их производительности (увеличения числа инструкций, выполняемых в единицу времени). Идея заключается в параллельном выполнении нескольких инструкций процессора. Суперскалярность — архитектура вычислительного ядра, использующая несколько декодеров команд, которые могут загружать работой множество исполнительных блоков. Планирование исполнения потока команд является динамическим и осуществляется самим вычислительным ядром. 7
  5. Отличается от скалярных процессоров, которые могут работать только с одним операндом в единицу времени. Абсолютное большинство процессоров являются скалярными или близкими к ним. Векторные процессоры были распространены в сфере научных вычислений, где они являлись основой большинства суперкомпьютеров начиная с 1980-х до 1990-х. Но резкое увеличение производительности и активная разработка новых процессоров привели к вытеснению векторных процессоров из сферы повседневных процессоров. 7
  6. Факторы влияющие на производительность векторного процессора Доля кода в векторной форме Длина вектора (векторного регистра) Количество векторных регистров Количество векторных модулей доступа к памяти (load-store) Таким образом, математические операции выполняются гораздо быстрее, основным ограничивающим фактором становится время, необходимое для извлечения данных из памяти. 7
  7. В большинстве современных микропроцессоров имеются векторные расширения. 7
  8. Intel MMX: 1997, Intel Pentium MMX, IA-32 AMD 3DNow!: 1998, AMD K6-2, IA-32 Apple, IBM, Motorola AltiVec: 1998, PowerPC G4, G5, IBM Cell/POWER Intel SSE (Streaming SIMD Extensions): 1999, Intel Pentium III Intel SSE2: 2001, Intel Pentium 4, IA-32 Intel SSE3: 2004, Intel Pentium 4 Prescott, IA-32 Intel SSE4: 2006, Intel Core, AMD K10, x86-64 AMD SSE5 (XOP, FMA4, CVT16): 2007, 2009, AMD Buldozzer Intel AVX: 2008, Intel Sandy Bridge ARM Advanced SIMD (NEON): ARMv7, ARM Cortex A MIPS SIMD Architecture (MSA): 2012, MIPS R5 Intel AVX2: 2013, Intel Haswell Intel AVX-512: 2013, Intel Xeon Skylake (2015), Intel Xeon Phi 7
  9. MMX (Multimedia Extensions — мультимедийные расширения) — коммерческое название дополнительного SIMD набора инструкций, разработанного компанией Intel и впервые представленного в 1997 году одновременно с линией процессоров Pentium MMX. Набор инструкций был предназначен для ускорения процессов кодирования/декодирования потоковых аудио и видеоданных.  &amp;lt;number&amp;gt;
  10. SSE - набор инструкций, разработанный Intel и впервые представленный в процессорах серии Pentium III как ответ на аналогичный набор инструкций 3DNow! от AMD, который был представлен годом раньше.  Технология SSE позволяла преодолеть две основные проблемы MMX: при использовании MMX невозможно было одновременно использовать инструкции сопроцессора, так как его регистры были общими с регистрами MMX, и возможность MMX работать только с целыми числами. SSE включает в архитектуру процессора восемь 128-битных регистров и набор инструкций, работающих со скалярными и упакованными типами данных. Управляющий регистр MXCSR (SIMD Floating-Point Control/Status Register) предназначен для маскирования/демаскирования SIMD-исключений, управления режимом округления и тд. &amp;lt;number&amp;gt;
  11. SSE2 расширяет набор инструкций SSE с целью полностью вытеснить MMX. Набор SSE2 добавил 144 новые команды к SSE, в котором было только 70 команд. Процессор, поддерживающий SSE2, требуется для установки Windows 8 и Microsoft Office 2013 &amp;lt;number&amp;gt;
  12. SSE3 Если говорить более конкретно, добавлены команды сложения и вычитания нескольких значений, хранящихся в одном регистре. Эти команды упростили ряд DSP- и 3D-операций. Существует также новая команда для преобразования значений с плавающей точкой в целые без необходимости вносить изменения в глобальном режиме округления. SSE4 Добавлены инструкции, ускоряющие компенсацию движения в видеокодеках, быстрое чтение из USWC памяти, множество инструкций для упрощения векторизации программ компиляторами. Кроме того, в SSE4.2 добавлены инструкции обработки строк 8/16 битных символов, вычисления CRC32 (контрольная сумма), POPCNT(подсчет числа единичных битов). &amp;lt;number&amp;gt;
  13. AVX предоставляет различные улучшения, новые инструкции и новую схему кодирования машинных кодов. Для большинства новых инструкций отсутствуют требования к выравниванию операндов в памяти. Однако рекомендуется следить за выравниванием на размер операнда, во избежание значительного снижения производительности. Подходит для интенсивных вычислений с плавающей точкой в мультимедиа-программах и научных задачах. Там, где возможна более высокая степень параллелизма, увеличивает производительность с вещественными числами. &amp;lt;number&amp;gt;
  14. &amp;lt;number&amp;gt;
  15. &amp;lt;number&amp;gt;
  16. &amp;lt;number&amp;gt;
  17. Результат помещается в младшее двойное слово (32-bit) операнда-назначения (xmm1). Три старших двойных слова из операнда-источника (xmm0) копируются в операнд-назначение (xmm1) Результат помещается в младшие 64 бита операнда-назначения (xmm1). Старшие 64 бита из операнда-источника (xmm0) копируются в операнд-назначение (xmm1) &amp;lt;number&amp;gt;
  18. &amp;lt;number&amp;gt;
  19. &amp;lt;number&amp;gt;
  20. &amp;lt;number&amp;gt;
  21. &amp;lt;number&amp;gt;
  22. &amp;lt;number&amp;gt;
  23. &amp;lt;number&amp;gt;
  24. &amp;lt;number&amp;gt;
  25. &amp;lt;number&amp;gt;
  26. &amp;lt;number&amp;gt;
  27. alignas(#) — стандартный для С++ переносимый способ задания настраиваемого выравнивания переменных и пользовательских типов. Используется в С++11 и поддерживается Visual Studio 2015. Можно использовать и другой вариант — __declspec( align( #)) declarator. Данные средства для управления выравниванием при статическом выделении памяти. Если необходимо выравнивание с динамическим выделением, необходимо использовать void* _aligned_malloc(size_t size, size_t alignment); Затем преобразуем указатель на массив a и b к типу _m128* при помощи reinterpret_cast, который позволяет преобразовывать любой указатель в указатель любого другого типа. После динамически выделим выравненную память при помощи уже упомянутой выше функции _aligned_malloc(N*sizeof(float), 16); Количество необходимых байт выделяем исходя из количества элементов с учетом размерности типа, а 16 это значение выравнивания, которое должно быть степенью двойки. А затем указатель на этот участок памяти приводим к другому типу указателя, чтобы с ним можно было бы работать с учетом размерности типа float как с массивом. &amp;lt;number&amp;gt;
  28. Впервые упоминание o поддержке JIT технологии SIMD было объявлено в блоге .NET в апреле 2014 года. Тогда разработчики анонсировали новую превью-версию RyuJIT, которая обеспечивала SIMD функциональность. Причиной добавления стала довольно высокая популярность запроса на поддержку C# and SIMD. Изначальный набор поддерживаемых типов был не большим и были ограничения по функциональности. Изначально поддерживался набор SSE, а AVX обещали добавить в релизе. Позже были выпущены обновления и добавлены новые типы с поддержкой SIMD и новые методы для работы с ними, что в последних версиях представляет обширную и удобную библиотеку для аппаратной обработки данных. Такой подход облегчает жизнь разработчика, который не должен писать CPU-зависимый код. Вместо этого CLR абстрагирует аппаратное обеспечение, предоставляя виртуальную исполняющую среду, которая переводит свой ​​код в машинные команды либо во время выполнения. Оставляя генерацию кода CLR, вы можете использовать один и тот же MSIL код на разных компьютерах с разными процессорами, не отказываясь от оптимизаций, специфических для данного конкретного CPU. Аппаратное ускорение может приводить к значительному повышению производительности при математическом и научном программировании, а также при программировании графики. Класс Vector предоставляет методы для сложения, сравнения, поиска минимума и максимума и многих других преобразований над векторами. При этом операции работают с использованием технологии SIMD. Остальные типы также поддерживают аппаратное ускорение и содержат специфические для них преобразования. Для матриц это может быть перемножение, для векторов евклидово расстояние между точками и т.д. &amp;lt;number&amp;gt;
  29. Несомненно, вы можете сделать больше на С++, чем на C#. Но вы действительно получаете кросс-процессорную поддержку на С#. Например, автоматический выбор между SSE4 и AVX. В целом, это не может не радовать. Ценой малых усилий мы можем получать от системы как можно большей производительности, задействуя все возможные аппаратные ресурсы. &amp;lt;number&amp;gt;
  30. &amp;lt;number&amp;gt;
  31. &amp;lt;number&amp;gt;
  32. &amp;lt;number&amp;gt;
  33. &amp;lt;number&amp;gt;
  34. Закладывает в сеть априорное знание о том, что объект может встретиться в любой части изображения &amp;lt;number&amp;gt;
  35. &amp;lt;number&amp;gt;
  36. Получили прирост в ~6 раз &amp;lt;number&amp;gt;
  37. &amp;lt;number&amp;gt;