Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Ontico
Оперативная память становится всё более дешёвой и производительной, что позволяет использовать её для хранения рабочего набора данных всё большего числа приложений. Хранение всех данных в оперативной памяти позволяет сделать их высоко доступными, а алгоритмы для работы с данными либо существенно упростить, либо ускорить, а иногда — и то, и другое.
Тезисы - http://www.highload.ru/2015/abstracts/1964.html
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Ontico
В процессе обновления высоконагруженных серверов раздачи видео (40Gbit/s с каждого сервера) со старого OpenSuSE 10.2 на новый CentOS 7 (время между релизами — 7 лет) мы столкнулись с рядом проблем — необъяснимый свопинг и запуски OOM killer, неравномерное распределение нагрузки по ядрам, обрывы соединений, скачки системной нагрузки на CPU.
В докладе будет рассказано о том, как мы боролись с этими проблемами и какие технологии для этого использовали.
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
Многие современные высоконагруженные системы построены с использованием очередей. Не является исключением и внутренний сервис обработки OAuth токенов, который создала наша команда. Исключением является то, что и в качестве основного хранилища, и в качестве всех очередей используется один и тот же продукт - Tarantool. Более того, мы поставили себе амбициозную цель по отказоустойчивости - полную доступность сервиса, когда уходят любые два из трёх датацентров, и успешно её достигли.
При решении мы столкнулись с массой интересных инженерных задач и в нашем докладе мы расскажем вам о том, какие технологии и подходы использовались. В частности, рассмотрим более детально такие вещи, как:
- создание deadline очереди и проблемы, с ней связанные;
- создание кольцевой очереди;
- интеграция между собой шардинга, Raft и очередей;
- как мы победили split brain ;)
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...Ontico
Сфера финансовых приложений и трейдинга выдвигает особые требования к системам обработки данных: ультракороткие задержки, конкурентные обновления (в т.ч. из разных процессов), репликация высокочастотных обновлений.
Существовавшие открытые key-value хранилища не справлялись, поэтому мы сделали свое — Chronicle Map.
В докладе я отвечу на вопросы:
+ Почему бывает эффективнее разбить систему, работающую с общим состоянием, на несколько отдельных процессов?
+ Зачем вам может захотеться распилить JVM на несколько частей?
+ Как добиться от key-value хранилища медианной latency меньше 1 микросекунды?
+ Как сделать репликацию, если она упирается в пропускную способность сети из-за слишком частых обновлений?
Развею миф о том, что Java — это медленно :)
Также, в докладе будет сравнение Chronicle Map с redis, one-nio и ConcurrentHashMap.
Хранение данных на виниле / Константин Осипов (tarantool.org)Ontico
В rfc1149 дан исчерпывающий обзор преимуществ голубиной почты для протокола IP: низкая пропускная способность, невысокая надёжность, простая топология сети. Для того чтобы дать адекватный ответ вызовам эпохи мемристоров и квантовых вычислений, Tarantool 1.7 содержит новый движок для хранения данных на классических жёстких дисках и флэш-накопителях: Vinyl. Tarantool известен своей скоростью, и мы постарались не ударить в грязь лицом и на этот раз.
В докладе я расскажу об устройстве нашего нового storage engine:
- как мы объединили in-memory технологию и LSM (log structured merge) деревья для достижения оптимальной производительности и утилизации ресурса накопителя,
- как работает multiversion concurrency control в Vinyl,
- основной компонент в промышленной реализации LSM дерева - merge scheduler, т.е. планировщик слияний и сборки мусора дерева. Я расскажу о подходе, который позволяет максимально снизить износ накопителя, при этом уложиться в заданные рамки производительности запросов.
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обменыAlexey Paznikov
ЛЕКЦИЯ 1. Основные понятия стандарта MPI. Дифференцированные обмены
Курс "Параллельные вычислительные технологии" (ПВТ), осень 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
http://cpct.sibsutis.ru/~apaznikov/teaching
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиFProg
В данном докладе рассматривается пример использования персистентной структуры данных - функциональной версии HAMT, для создания main memory базы данных. Данная реализация HAMT располагается в shared memory и используется для хранения индексов.
Рассматриваются задачи, которые были быстро и эффективно решены благодаря использованию неизменяемых структур данных (управление изменениями, поддержка ACID-свойств), а также проблемы, возникшие из-за этого. Также, рассмотрен метод реализации персистентного графа, использующий изменяемые данные и позволяющий достичь большей производительности, по сравнению с аналогичной, неизменяемой структурой данных.
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Ontico
Оперативная память становится всё более дешёвой и производительной, что позволяет использовать её для хранения рабочего набора данных всё большего числа приложений. Хранение всех данных в оперативной памяти позволяет сделать их высоко доступными, а алгоритмы для работы с данными либо существенно упростить, либо ускорить, а иногда — и то, и другое.
Тезисы - http://www.highload.ru/2015/abstracts/1964.html
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...Ontico
В процессе обновления высоконагруженных серверов раздачи видео (40Gbit/s с каждого сервера) со старого OpenSuSE 10.2 на новый CentOS 7 (время между релизами — 7 лет) мы столкнулись с рядом проблем — необъяснимый свопинг и запуски OOM killer, неравномерное распределение нагрузки по ядрам, обрывы соединений, скачки системной нагрузки на CPU.
В докладе будет рассказано о том, как мы боролись с этими проблемами и какие технологии для этого использовали.
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
Многие современные высоконагруженные системы построены с использованием очередей. Не является исключением и внутренний сервис обработки OAuth токенов, который создала наша команда. Исключением является то, что и в качестве основного хранилища, и в качестве всех очередей используется один и тот же продукт - Tarantool. Более того, мы поставили себе амбициозную цель по отказоустойчивости - полную доступность сервиса, когда уходят любые два из трёх датацентров, и успешно её достигли.
При решении мы столкнулись с массой интересных инженерных задач и в нашем докладе мы расскажем вам о том, какие технологии и подходы использовались. В частности, рассмотрим более детально такие вещи, как:
- создание deadline очереди и проблемы, с ней связанные;
- создание кольцевой очереди;
- интеграция между собой шардинга, Raft и очередей;
- как мы победили split brain ;)
Chronicle Map — key-value хранилище для трейдинга на Java / Левентов Роман (C...Ontico
Сфера финансовых приложений и трейдинга выдвигает особые требования к системам обработки данных: ультракороткие задержки, конкурентные обновления (в т.ч. из разных процессов), репликация высокочастотных обновлений.
Существовавшие открытые key-value хранилища не справлялись, поэтому мы сделали свое — Chronicle Map.
В докладе я отвечу на вопросы:
+ Почему бывает эффективнее разбить систему, работающую с общим состоянием, на несколько отдельных процессов?
+ Зачем вам может захотеться распилить JVM на несколько частей?
+ Как добиться от key-value хранилища медианной latency меньше 1 микросекунды?
+ Как сделать репликацию, если она упирается в пропускную способность сети из-за слишком частых обновлений?
Развею миф о том, что Java — это медленно :)
Также, в докладе будет сравнение Chronicle Map с redis, one-nio и ConcurrentHashMap.
Хранение данных на виниле / Константин Осипов (tarantool.org)Ontico
В rfc1149 дан исчерпывающий обзор преимуществ голубиной почты для протокола IP: низкая пропускная способность, невысокая надёжность, простая топология сети. Для того чтобы дать адекватный ответ вызовам эпохи мемристоров и квантовых вычислений, Tarantool 1.7 содержит новый движок для хранения данных на классических жёстких дисках и флэш-накопителях: Vinyl. Tarantool известен своей скоростью, и мы постарались не ударить в грязь лицом и на этот раз.
В докладе я расскажу об устройстве нашего нового storage engine:
- как мы объединили in-memory технологию и LSM (log structured merge) деревья для достижения оптимальной производительности и утилизации ресурса накопителя,
- как работает multiversion concurrency control в Vinyl,
- основной компонент в промышленной реализации LSM дерева - merge scheduler, т.е. планировщик слияний и сборки мусора дерева. Я расскажу о подходе, который позволяет максимально снизить износ накопителя, при этом уложиться в заданные рамки производительности запросов.
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обменыAlexey Paznikov
ЛЕКЦИЯ 1. Основные понятия стандарта MPI. Дифференцированные обмены
Курс "Параллельные вычислительные технологии" (ПВТ), осень 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
http://cpct.sibsutis.ru/~apaznikov/teaching
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиFProg
В данном докладе рассматривается пример использования персистентной структуры данных - функциональной версии HAMT, для создания main memory базы данных. Данная реализация HAMT располагается в shared memory и используется для хранения индексов.
Рассматриваются задачи, которые были быстро и эффективно решены благодаря использованию неизменяемых структур данных (управление изменениями, поддержка ACID-свойств), а также проблемы, возникшие из-за этого. Также, рассмотрен метод реализации персистентного графа, использующий изменяемые данные и позволяющий достичь большей производительности, по сравнению с аналогичной, неизменяемой структурой данных.
Современная операционная система: что надо знать разработчику / Александр Кри...Ontico
Мы проговорим про связь приложения и ОС, какие компоненты есть в современной ОС на примере Linux, как настройки этих компонент могут повлиять на приложение.
Я расскажу про планировщик процессов, дисковый и сетевой ввод-вывод и соответствующие планировщики, управление памятью - как это все в общих чертах работает и как его потюнить.
Similar to Архитектура и программирование потоковых многоядерных процессоров для научных рассчетов. Лекция 5. Пример вычислительного ядра - задача у (20)
Архитектура и программирование потоковых многоядерных процессоров для научных рассчетов. Лекция 5. Пример вычислительного ядра - задача у
1. Архитектура и программирование
потоковых многоядерных процессоров
для научных расчётов
Лекция 5. Пример вычислительного ядра
– задача умножения матриц Текстуры
матриц. Текстуры.
Атомарные функции. Библиотека CUTIL
2. Процедура разработки программы
Общий подход к програмированию
Разбить задачу на элементарные блоки данных, над которыми
выполняется стандартный алгоритм обработки (единый для
всех б
блоков)
)
Разбить за-/вы- гружаемые данные на элементарные
непересекающиеся блоки которые каждый из процессов
блоки,
прочтёт/запишет
Определить конфигурацию грида/блока позволяющее
грида/блока,
Оптимальное размещение промежуточных данных в регистрах и общей
памяти
Оптимальную вычислительную загрузку потоковых процессоров
Определить график когерентного обращения к памяти
процессами при загрузке данных
3. Вычислительная конфигурация
GPU
Host
Device
Grid 1
Kernel
1
Block
(0, 0)
Block
(1, 0)
Block
(2, 0)
Block
(0,
(0 1)
Block
(1,
(1 1)
Block
(2,
(2 1)
Grid 2
Kernel
2
Block (1, 1)
Thread Thread Thread Thread Thread
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(4, 0)
Thread Thread Thread Thread Thread
( )
(0, 1)
( )
(1, 1)
( )
(2, 1)
( )
(3, 1)
( )
(4, 1)
Thread Thread Thread Thread Thread
(0, 2)
(1, 2)
(2, 2)
(3, 2)
(4, 2)
Процессы объединяются в
блоки (blocks), внутри
которых они имеют общую
р
щу
память (shared memory) и
синхронное исполнение
Блоки объединяются в сетки
(grids)
Нет возможности предсказать
очерёдность запуска блоков в
сетки
Между блоками нет и не может
быть (см. выше) общей памяти
4. Пример программы для GPU
умножение матриц -1
bx
0
1
2
tx
BLOCK_W
WIDTH
BLOCK_W
WIDTH
Hb
Ha
M
N
BLOCK_S
SIZE
Разбить задачу на элементарные блоки
данных, над которыми выполняется
стандартный алгоритм обработки
(единый для всех блоков)
Каждый блок вычисляет некоторую
небольшую область результата
у
р у
Каждый тред в блоке вычисляет один элемент
этой области
bsize-1
012
P
0
by
0
1
2
1
ty
Psub
bsize-1
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
Wa
Wb
2
5. Пример программы для GPU
умножение матриц -2
bx
0
1
2
tx
BLOCK_W
WIDTH
BLOCK_W
WIDTH
Hb
Ha
M
N
BLOCK_S
SIZE
Разбить данные на элементарные блоки
(непересекающиеся), которые каждый из
процессов прочтёт/запишет
Необходимые области исходных матриц
разбиваются на квадратные области
Каждый из тредов читает один элемент из этих
областей в разделяемую память
bsize-1
012
P
0
by
0
1
2
1
ty
Psub
bsize-1
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
Wa
Wb
2
6. Пример программы для GPU
умножение матриц -3
bx
0
1
2
tx
Hb
Ha
M
BLOCK_W
WIDTH
BLOCK_W
WIDTH
Блок = 16x16= 256
тредов больше чем 192,
меньше чем 512
N
BLOCK_S
SIZE
Определить конфигурацию грида/блока,
позволяющее
Оптимальное размещение промежуточных
данных в регистрах и общей памяти
Оптимальную вычислительную загрузку
потоковых процессоров
bsize-1
012
P
0
Целое количество варпов
в блоке
0
1
2
by
1
Размеры грида
определяются размерами
исходных матриц
ty
Psub
bsize-1
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
Wa
Wb
2
7. Пример программы для GPU
умножение матриц -4
bx
0
1
2
tx
Hb
Ha
M
BLOCK_W
WIDTH
BLOCK_W
WIDTH
Регистровая память
расходуется
незначительно
N
BLOCK_S
SIZE
Размер разделяемой памяти = 16KB на
мультипроцессор (максимальное
количество памяти для б
блока)
)
В разделяемую память мультипроцессора
поместятся данные от 8 блоков
bsize-1
012
P
0
Для определения
количества регистров,
by
приходящееся на один 1
тред нужно смотреть
PTX код
0
1
2
ty
Psub
bsize-1
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
BLOCK_WIDTH
BLOCK WIDTH
Wa
Wb
2
8. Хост функция
Хост-функция
умножения матриц
#define BLOCK SIZE 16
BLOCK_SIZE
__global__ void Muld(float*, float*, int, int, float*);
void Mul(const float* A, const float* B, int hA, int wA, int wB, float* C) {
int size;
// Load A and B t the device
L d
d to th d i
float* Ad; size = hA * wA * sizeof(float); cudaMalloc((void**)&Ad, size);
cudaMemcpy(Ad, A, size, cudaMemcpyHostToDevice);
float* Bd; size = wA * wB * sizeof(float); cudaMalloc((void**)&Bd, size);
cudaMemcpy(Bd, B, size, cudaMemcpyHostToDevice);
// Allocate C on the device
float* Cd;
size = hA * wB * sizeof(float);
cudaMalloc((void**)&Cd, size);
// Compute the execution configuration assuming the matrix dimensions are multiples of BLOCK_SIZE
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGrid(wB / dimBlock.x, hA / dimBlock.y);
// Launch the device computation
Muld<<<dimGrid, dimBlock>>>(Ad, Bd, wA, wB, Cd);
// Read C from the device
cudaMemcpy(C, Cd, size, cudaMemcpyDeviceToHost);
// Free device memory
cudaFree(Ad); cudaFree(Bd); cudaFree(Cd); }
9. GPU ядро умножения матриц
__global__ void Muld(float* A, float* B, int wA, int wB, float* C) {
global
A
B
wA
wB
int bx = blockIdx.x; // Block index
int by = blockIdx.y;
int tx
i t t = threadIdx.x; // Thread index
th
dId
Th
di d
int ty = threadIdx.y;
int aBegin = wA * BLOCK_SIZE * by; // Index of the first sub-matrix of A processed by the block
int aEnd = aBegin + wA - 1; // Index of the last sub-matrix of A processed by the block
int aStep = BLOCK_SIZE; // Step size used to iterate through the sub-matrices of A
int bBegin = BLOCK_SIZE * bx; // Index of the first sub-matrix of B processed by the block
int bStep = BLOCK_SIZE * wB; // Step size used to iterate through the sub-matrices of B
float Csub = 0; // The element of the block sub-matrix that is computed by the thread
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep) {
// Shared memory for the sub-matrix of A
__shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
// Shared memory for the sub-matrix of B
__shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE];
10. GPU ядро умножения матриц
(продолжение)
As[ty][tx] = A[a + wA * ty + tx]; // Load the matrices from global memory to shared memory;
Bs[ty][tx] = B[b + wB * ty + tx]; // each thread loads one element of each matrix
__syncthreads(); // Synchronize to make sure the matrices are loaded
y
()
y
// Multiply the two matrices together;
// each thread computes one element
// of the block sub-matrix
for (int k = 0; k < BLOCK_SIZE; ++k)
Csub += As[ty][k] * Bs[k][tx];
// Synchronize to make sure that the preceding
// computation is done before loading two new
// sub-matrices of A and B in the next iteration
__syncthreads();
}
// Write the block sub-matrix to global memory;
// each thread writes one element
int c = wB * BLOCK_SIZE * by + BLOCK_SIZE * bx;
C[c + wB * ty + tx] = Csub;
}
11. Уровень производительности
Для матрицы 1024*1024
Автоматическое распределение : 3.0 сек - 45 GFLOPS
1 блок на SM
: 3.6 сек. - 35 GFLOPS
2 блока на SM
: 3.0 сек. - 45 GFLOPS
Очевидно,
Очевидно ограничивающим фактором является
требование запуска 2 блоков на SM, а не ограничение
по разделяемой памяти (8 блоков на SM)
Развёртывание циклов помогает (развёрнуто 16 раз)
Развернутая программа (автомат) : 1.6 сек. - 80 GFLOPS
1 блок на SM
: 2.1 сек. - 61 GFLOPS
2 блока на SM
: 1.6 сек. - 80 GFLOPS
12. Уровень производительности
(продолжение)
Возможный альтернативный график вычислений
Loop {
Load to Shared Memory
y
Syncthread()
Load to Shared Memory
Syncthread()
Loop {
Compute current subblock
Compute current subblock
C
bbl k
Load to Shard Memory
Syncthreads()
}
Syncthreads()
}
13. Texture Processor Cluster (TPC)
TPC
SM 0
Instruction Fetch
T
Instruction L
e
1 Cache
Instruction Decode
x
T
t
e
u
x
I
Shared Memory
SP 0
R
SP 1
R
R
SP 5
SP 2
R
R
SP 6
R
R
SP 7
F
r
t
e
u
U
L
S
D
F
Constant L
r
&
SP 4
SP 3
S
R
e
U
L
1 Cache
2
SM 1
1
C
Instruction Fetch
Instruction L
U
1 Cache
a
Instruction Decode
I t
ti D
d
C
n
a
i
c
t
h
e
c
Shared Memory
SP 0
S
R
R
SP 1
R
R
SP 5
h
SP 4
F
U
TEX – Т
Текстурный блок – логика
йб
адресации текстурных массивов в 1D,
2D, 3D
+ L1 Кэш Текстур
S
F
SP 2
R
R
SP 6
SP 3
R
R
SP 7
Constant L
1 Cache
Load/Store
U
e
L2 Кэш инструкций и данных для обоих
SM
x2 Потоковых Мультипроцессора
(St ea
(Streaming Multiprocessor)
g u t p ocesso )
x8 потоковых процессоров (streaming
processors) = 8 MAD/clock cycle
Регистры для хранения промежуточных
р
р
р
у
результатов у выполняемых тредов =>
больше тредов лучше скрыты операции
чтения, но межет не хватить регистров
14. Использование текстур
(обзор)
Текстуры - удобный способ обращения с табличными
исходными данными
Кэшированы – для каждых 2 SM – общий L1 кэш, общий L2
К
2-х
б
й
б
й
кэш для всего кристалла
Замена разделяемой памяти для RO операндов
Нет ё
Н жёстких требований к правильности адресации
б
й
Адреса – числа с плавающей точкой (возможно с
нормализацией)
Позволяют выделять объекты с адресом, находящимся между
табличными значениями
Аппоксимация ближайшим
Линейная и билинейная аппроксимация (
Л
й
б
й
(исходя из значений
й
соседей)
Варианты “tile” и “center”
Поведение текстуры при выходе адреса за пределы сетки
15. Использование текстур
(детали)
Объявление вне тела функции - texture<Type, Dim, ReadMode> texRef;
Type = тип
Dim = 1 | 2
ReadMode = cudaReadModeNormalizedFloat | CudaReadModeElementType
Определение – привязывание объявленной ссылки на 1D (линейный массив)
или 2D (CudaArray) объекту в глобальной памяти
cudaBindTexture()
cudaBindTextureToArray()
cudaUnbindTexture()
Использование – “texture fetch”
1D-массив
Texture_type tex1Dfetch(texture<uchar4, 1, cudaReadModeNormalizedFloat> texRef,int x);
2D-массив
Texture_type tex1D(texture<Type, 1, readMode> texRef, float x);
Texture_type tex2D(texture<Type, 2, readMode> texRef, float x, float y);
16. Использование текстур
(пример часть 1)
texture<float, 2, cudaReadModeElementType> tex; // declare texture reference for 2D float texture
__global__ void transformKernel( float* g_odata, int width, int height, float theta)
{
// calculate normalized texture coordinates
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
float u = x / (float) width;
float v = y / (float) height;
u -=
v -=
float
float
0.5f; // transform coordinates
0.5f;
tu = u*cosf(theta) - v*sinf(theta) + 0.5f;
tv = v*cosf(theta) + u*sinf(theta) + 0.5f;
// read from texture and write to global memory
g_odata[y*width + x] = tex2D(tex, tu, tv);
}
17. Использование текстур
(пример часть 2)
// set texture parameters
tex.addressMode[0] = cudaAddressModeWrap;
tex.addressMode[1] = cudaAddressModeWrap;
p
tex.filterMode = cudaFilterModeLinear;
tex.normalized = true; // access with normalized texture coordinates
// Bind the array to the texture
y
CUDA_SAFE_CALL( cudaBindTextureToArray( tex, cu_array, channelDesc));
dim3 dimBlock(8, 8, 1);
dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
// warmup
transformKernel<<< dimGrid, dimBlock, 0 >>>( d_data, width, height, angle);
CUDA_SAFE_CALL( cudaThreadSynchronize() );
// execute the kernel
transformKernel<<< dimGrid dimBlock 0 >>>( d data width, height, angle);
dimGrid, dimBlock,
d_data, width height
18. Обращение с памятью из ворпа
НЕАТОМАРНЫЕ ИНСТРУКЦИИ (G80)
ЕСЛИ какая-либо инструкция исполняемая ворпом пишет в одно
место в глобальной или общей памяти
ТО количество записей и их очерёдность недетерминированы
ОДНАКО по крайней мере одна запись состоится
АТОМАРНЫЕ ИНСТРУКЦИИ (G92+)
ЕСЛИ какая-либо инструкция исполняемая ворпом
пишет/читает/модифицирует одно место в глобальной памяти
ТО их очерёдность записей недетерминирована
ОДНАКО все записи состоятся последовательно
19. Атомарные функции
Функции чтения/модификации/записи данных в глобальную
память – основа построения алгоритмов стекового
декодирования
Работают только с целыми значениями (!)
Гарантируют неизменность операнда в процессе
операции
Арифметические функции: atomicAdd,atomicSub, atomicExch,
atomicMax, atomicInc, atomicDec
int atomicAdd(int* address, int val);
Функция atomicCAS – Compare and store
int atomicCAS(int* address, int compare, int val);
Битовые функции atomicAnd, atomicOr, atomicXor
int atomicAnd(int* address, int val);
20. Библиотека cutil
Набор утилит для различных служебных целей (cut* - функции)
Макросы типа CUDA_SAFE_CALL - различные ситуции, с
синхронизацией,
синхронизацией без неё для эмуляции
неё,
Утилиты профайлинга
измерение длительности исполнения
CUT_SAFE_CALL(
CUT SAFE CALL( cutCreateTimer( &timer));
CUT_SAFE_CALL( cutStartTimer( timer));
CUT_SAFE_CALL( cutStopTimer( timer));
CUT_SAFE_CALL(
CUT SAFE CALL( cutDeleteTimer(&timer));
Определение конфликтных ситуаций операций чтения
И т.д. => см cutil.h
Находится в директории common в составе SDK
В отличии от других библиотек предоставляется в виде исходных
текстов
Необходимо скомпилировать до работы над своим проектом
21. Итоги лекции
В результате лекции студенты должны :
Получить практический пример составления
вычислительного ядра для типовой задачи.
Получить представление о свойствах текстур и
возможности их применения в научных вычислениях
Получить представление о свойствах и возможности
применения в научных вычислениях атомарных функций
Достаточные знания для начала самостоятельной работы