TMPA-2015: Automated Testing of Multi-thread Data Structures Solutions Linerializability

Post on 12-Apr-2017

2694 Views

Category:

Science

1 Downloads

Preview:

Click to see full reader

Transcript

Антон Евдокимов (aevdokimov@devexperts.com)

Дмитрий Цителов (cit@devexperts.com)

Роман Елизаров (elizarov@devexperts.com)

Виталий Трифанов (trifanov@devexperts.com)

Автоматическое тестирование

линеаризуемости реализаций

многопоточных структур

данных

В чем проблема?

─ Процессоры многоядерные

─ Нужно писать многопоточный код

─ Это не так просто

─ В многопоточной среде появляются

специфические проблемы

─ Одновременный доступ к разделяемым

ресурсам

В чем проблема?

В чем проблема?

─ Стандартные подходы к тестированию

не работают

─ Но проверять корректность

реализации все равно хочется

Линеаризуемость

─ Любое параллельное исполнение эквивалентно

некоторому последовательному

Метод

─ Взять небольшое количество потоков

─ В каждом несколько операций над

структурой данных

─ Запустить много-много раз и

попытаться объяснить результаты

последовательной перестановкой

─ Повторить

Метод

Границы применимости метода

─ Подходит для популярных структур

данных

─ Очереди, множества, хеш-таблицы…

─ Но

─ Структура данных не зависит от

внешней среды

─ Не блокируется

─ Метод точен, но не полон

Очередь

Генерация тестовых наборов

─ Наивно?

─ Операции

─ Изменяют структуру данных

─ Не изменяют

─ Аргументы

─ Влияют на логику поведения

структуры данных

─ Не влияют

Генерация тестовых наборов

Генерация тестовых наборов

Генерация тестовых наборов

P Q

offer(1);

offer(2);

poll();

poll();

Последовательные исполнения

─ Перестановки исходного набора

операций

─ С сохранением порядка операций для

каждого потока

Последовательные исполнения

P Q

offer(1);

offer(2);

poll();

poll();

offer(1); poll() {1}; offer(2); poll() {2};

Последовательные исполнения

offer(1); offer(2); poll() {1}; poll() {2};

offer(1); poll() {1}; offer(2); poll() {2};

offer(1); poll() {1}; poll() {Exception}; offer(2);

poll() {Exception}; poll() {Exception}; offer(1); offer(2);

poll() {Exception}; offer(1); offer(2); poll() {1};

poll() {Exception}; offer(1); poll() {1}; offer(2);

Параллельные исполнения

─ Множественные запуски

─ Синхронизация старта

─ Все служебные структуры создаем

вне многопоточной системы

─ Можно вызывать методы через

Reflection API, но используется ASM

─ Две фазы запусков (без/с задержками)

Проверка

─ Ищем последовательное исполнение,

соответствующее по результатам

параллельному

─ Если не нашли, то структура

нелинеаризуема!

offer(1); poll() {1}; offer(2); poll() {1};

Результаты

─ Синтетические примеры

─ Очередь, счетчик, некоторые другие

─ Потеря synchronized, volatile,

ошибочное использование

неатомарных переменных

─ Нашлись наборы операций,

приводящие к ошибке

Результаты

─ java.util.concurrent ✓

─ Google Guavа ✓

Результаты

─ jctools [1]

─ MpmcArrayQueue ✗

─ zchannel [2]

─ GenericMPMCQueue ✗

─ high_scale_lib [3]

─ NonBlockingHashMap ✗

[1] https://github.com/JCTools/JCTools

[2] http://landz.github.io/

[3] https://github.com/stephenc/high-scale-lib

Результаты

─ zchannel – GenericMPMCQueue

P Q

offer(9); {true}

poll(); {null}

offer(1); {true}

poll(1); {1}

Результаты

Структура данных Время (мс); мин-макс (средн.)

Counter 4 – 110 (33)

Queue 5 – 38786 (8635)

Accounts 3 – 50606 (18697)

NonBlockingSetInt 52 – 10414 (4291)

NonBlockingHashSet 5 – 66975 (16111)

MpmcArrayQueue(2) 2352 – 45628 (19974)

MPMCQueue(2) 1814 – 33958 (19714)

MPMCQueue(16) 1877 – 33858 (8651)

LockFreeQueue 8825 – 342199 (135202)

Что дальше?

─ Генерация параллельных исполнений

с помощью управляемого

переключения между потоками

─ Конкретная последовательность

инструкций

─ Лучшее покрытие состояний

Где посмотреть

─ Lincheck

─ https://github.com/Devexperts/lin-check

─ E-mail

─ dxlab@devexperts.com

Вопросы?

Спасибо

top related