SlideShare uma empresa Scribd logo
1 de 12
Baixar para ler offline
Интервью с Дмитрием Вьюковым –
автором верификатора Relacy Race
Detector (RRD)
Автор: Андрей Карпов

Дата: 06.04.2009


Аннотация
Интервью с Дмитрием Вьюковым - автором инструмента Relacy Race Detector (RRD) для
верификации параллельных приложений. В статье вы узнаете об истории создания RRD, его
основных возможностях, а также о некоторых других аналогичных инструментах и их отличии от
RRD.


Введение
Вашему вниманию предлагается интервью с автором верификатора Relacy Race Detector (RRD) для
тестирования многопоточных алгоритмов. В интервью обсуждаются перспективы использования
RRD и других инструментов для проверки параллельных приложений и смежные темы.

Вопросы задает (вопросы будут выделены жирным текстом):

Карпов Андрей Николаевич. Один из основателей компании "Системы программной
верификации", занимается разработкой инструментов для статического анализа исходного кода.
Участвует в развитии инструментов Viva64 и VivaMP для тестирования 64-битных и параллельных
приложений. Поддерживает открытую библиотеку VivaCore, предназначенную для разбора
(парсинга) Си/Си++ кода.

На вопросы отвечает:

Вьюков Дмитрий Сергеевич. Разработчик высокопроизводительного программного обеспечения
на Си/Си++ в области клиент/серверных систем и сетевых серверов. В свободное время
увлекается разработкой инновационных алгоритмов синхронизации, разработкой моделей
программирования для многоядерных процессоров и систем верификации многопоточного кода.
Автор инструмента Relacy Race Detector (RRD).


Текст интервью


Здравствуйте, Дмитрий. Расскажите немного о себе, чем
занимаетесь и в каких проектах участвуете?
В меру своих сил я занимаюсь всем, что связано с многопоточностью и параллелизмом:
масштабируемыми алгоритмами синхронизации, моделями программирования для
многоядерных процессоров, верификацией многопоточного кода и так далее. Свои разработки
касательно алгоритмов синхронизации я публикую в группе Scalable Synchronization Algorithms.
Так же я разработал и поддерживаю инструмент верификации многопоточного кода Relacy Race
Detector (RRD).


Что подтолкнуло Вас к созданию верификатора Relacy Race
Detector?
RRD появился достаточно спонтанно. Предпосылок для его создания было три.

Первая - я занимаюсь разработкой алгоритмов синхронизации, а тестирование и локализация
ошибок в них - очень и очень серьёзная проблема: ошибки проявляются очень редко или вообще
не проявляются на некоторых компьютерах (допустим на компьютерах с менее чем 4-мя
процессорами, или на компьютерах с некоторой версией операционной системы). А если ошибка
всё-таки регулярно проявляется, то часто бывает очень сложно понять истинную первопричину
ошибки (в какой момент и что именно начинает идти "не так"). Это породило мысль, что неплохо
было бы иметь какие-то "инструменты" для решения проблемы.

Вторая предпосылка - за время работы с алгоритмами синхронизации накопился некоторый багаж
приёмов, которые я применял для тестирования и локализации ошибок. Один из основных - это
вставка в код программы большого количества примерно таких строчек:

if ((rand() % 1000) == 0) Sleep (rand() % 10);

и последующее стресс-тестирование работы программы. Этот приём позволяет добиться
выполнения значительно большего количества различных чередований (interleaving) потоков.
Собственно это, по большому счёту, и является основным принципом работы RRD.

Третьей предпосылкой явилось то, что в какой-то момент я, наконец, понял, как можно собрать
все мои приёмы в автоматический инструмент тестирования, как можно простым способом
проводить необходимое инструментирование программы, и как при этом можно обеспечить
высокую эффективность работы инструмента. Дальше было дело техники - первый рабочий
прототип (который реально обнаружил одну специально внесённую ошибку в простой алгоритм)
появился в тот же день ближе к ночи. Хотя, конечно, доведение RRD до более-менее пригодного
для реальной работы вида заняло значительно больше времени.


Расскажите, пожалуйста, о RRD более подробно. Какие принципы и
алгоритмы лежат в его основе? В каких областях его применение
наиболее перспективно?
RRD является средством динамической верификации без запоминания состояний. Он
предназначен, прежде всего, для тестирования многопоточных алгоритмов (алгоритмов
синхронизации, многопоточных структур данных и так далее). Для пользователя работа с RRD
выглядит примерно следующим образом. Вначале реализуется тестируемый алгоритм.
Реализация может быть выражена через примитивы синхронизации C++09, POSIX threads
(pthread), Win32 API, C#/.NET, Java. Однако необходимо использовать указанные API не напрямую,
а через "обёртки", предоставляемые RRD; синтаксис практически идентичен, однако имеются
некоторые отличия. Когда тестируемый алгоритм реализован, необходимо реализовать один или
несколько юнит-тестов (unit test) для алгоритма. Далее можно запускать их на исполнение, при
этом RRD позаботится об эффективном исполнении тестов, то есть будет проверено как можно
больше различных чередований (interleaving) потоков. Во время исполнения каждого
чередования RRD будет делать множество различных проверок корректности алгоритма, включая
как пользовательские утверждения (asserts) и инварианты (invariants), так и базовые встроенные
проверки - гонки (data races), обращения к освобожденной памяти, двойные освобождения
памяти, утечки памяти, взаимные блокировки (deadlocks), активные блокировки (livelocks),
некорректные использования API (например, рекурсивный захват нерекурсивного мьютекса), и
другие. При обнаружении ошибки RRD выведет подробную историю исполнения, которая привела
к ошибке. Имея на руках такую историю, локализация ошибки становится делом техники (история
содержит такие детали как отклонения от последовательно согласованного (sequentially
consistent) порядка, инстансы ABA проблемы, ложные пробуждения на условных переменных
(condition variable) и т.д.).

Большое количество встроенных проверок и пристрастность, с которой RRD их проводит,
позволяют во многих случаях не делать в тесте вообще никаких пользовательских проверок.
Например, если мы тестируем reader-writer мьютекс, то достаточно лишь создать несколько
потоков, которые будут захватывать мьютекс на чтение и считывать какую-то переменную, и
несколько потоков, которые захватывают мьютекс для записи и изменяют эту же переменную.
Если алгоритм мьютекса не обеспечивает взаимного исключения, то автоматически будет
обнаружена гонка на защищаемой переменной; если алгоритм может входить во взаимную
блокировку или активную блокировку, то RRD тоже обнаруживает это автоматически. Однако если
мы тестируем очередь типа производитель-потребитель (producer-consumer), и очередь должна
обеспечивать FIFO порядок сообщений, то такую проверку придётся запрограммировать вручную.

Теперь немного о внутреннем устройстве RRD, и об используемых алгоритмах. RRD
инструментирует все обращения к переменным, примитивам синхронизации и API вызовам. Это
даёт возможность встроить в них все необходимые проверки, а так же возможность полностью
управлять переключением потоков. RRD содержит 3 планировщика потоков (выбор планировщика
производится при запуске теста).

Самый простой планировщик - это так называемый случайный планировщик (random scheduler),
после каждого элементарного действия программы (обращении к переменной, примитиву
синхронизации, API вызову) планировщик выбирает случайный поток и переключает управление
на него. Этот планировщик хорош для первоначального тестирования алгоритма, т.к. он не даёт
исчерпывающей проверки, но зато работает очень быстро.

Второй планировщик производит полный систематический перебор всех возможных чередований
потоков (full search scheduler), однако его недостаток в очень длительном времени верификации,
на практике его целесообразно применять только для небольших тестов.

Последний, третий, планировщик самый интересный и полезный - это так называемый
планировщик с ограничением на количество переключений потоков (context bound scheduler). Он
производит систематический перебор чередования потоков, однако при этом проверяет только
чередования, в которых общее количество добровольных переключений потоков не больше
некоторого заданного числа. За счёт этого он даёт очень хороший компромисс между качеством
проверки и временем работы. Так же следует отметить, что все планировщики являются
справедливыми (fair), это даёт возможность тестировать формально не терминирующие
алгоритмы, т.е. алгоритмы, содержащие циклы, которые могут повторяться потенциально
неограниченное число раз.
На каких условиях распространяется RRD?
RRD может свободно использоваться для некоммерческой разработки с открытыми исходными
кодами, для образовательных целей, для академических разработок с непатентуемыми
результатами, а так же для персонального некоммерческого использования. Для всех остальных
применений RRD является платным. Хотя возможно рассмотрение частных случаев; например, я
имел некоторые предварительные беседы касательно предоставления специальных лицензий
для разработки ядра Linux (там есть некоторые скользкие моменты, касающиеся патентованных
алгоритмов и коммерциализации), а так же для разработки Intel Threading Building Blocks (который
распространяется под двойной лицензией, одна из которых коммерческая).


Вы можете порекомендовать какие-то дополнительные ресурсы,
связанные с RRD? Где можно скачать RRD?
Основной ресурс, посвященный RRD расположен по адресу:

http://www.viva64.com/go.php?url=194

Там можно скачать последнюю версию библиотеки, найти некоторые материалы по RRD, а так же
задавать вопросы. Дистрибутив RRD включает ряд примеров, которые могут помочь освоить RRD.


Вы, наверное, знакомы со многими другими верификаторами
параллельных приложений. Действительно ли не один из них не
реализует диагностики, которые позволяет производить RRD? В
чем их отличие от RRD?
Да, конечно, до создания RRD я смотрел на множество средств верификации (Intel Thread Checker,
Chord, Zing, Spin, RacerX, CheckFence, Sober, Coverity Thread Analyzer, CHESS, KISS, PreFast, Prefix,
FxCop) в надежде найти то, что нужно для моих целей. Однако большинство инструментов
рассчитаны, так сказать, на разработчиков конечных прикладных программ, а не на разработчиков
алгоритмов синхронизации и библиотек поддержки параллелизма. Ни один из инструментов не
даёт того уровня детализации и точности моделирования свободного доступа к памяти (Relaxed
Memory Order) [*], который был необходим мне. Образно, если упомянутые средства могут
верифицировать программу, использующую OpenMP, то RRD может верифицировать саму
реализацию OpenMP.

[*] Примечание. Свободный доступ к памяти (Relaxed Memory Order, RMO) - метод работы с
памятью, когда процессор использует все средства кэширования и динамического
переупорядочения команд, и не пытается обеспечить никаких требований к упорядоченности
выборки и сохранению операндов в основной памяти. Иногда такой режим называют
"расслабленная модель памяти".


Вы назвали множество различных инструментов. Не могли бы Вы
вкратце рассказать о них? Многие читатели, вероятно, даже не
слышали о большинстве этих инструментов.
Сразу оговорюсь, что с большинством инструментов я не знакомился практически (установка,
запуск примеров, применение в собственных проектах). Я знакомился с ними поверхностно, так
как из общих описаний мне становилось понятно, что это не то, что мне нужно; и дальше
знакомиться не имело смысла. Поэтому я, наверное, не смогу рассказать много интересного для
конечных пользователей, но тем не менее...

Могу рассказать про инструмент Spin, который несколько приближается по свойствам к RRD, и я
знаю, что он использовался для верификации некоторых алгоритмов синхронизации для ядра
Linux и для Threading Building Blocks. Spin - это, наверное, самый старый и основательный
инструмент такого рода, его корни уходят в начало 80-ых годов, по нему написан ряд книг, и, что
очень приятно, он активно развивается и по сей день. Spin включает множество вариантов
проверки - динамическая проверка с запоминанием состояний, без запоминания, полная
проверка модели программы, не полная проверка модели программы (для очень больших
программ) и так дадее, всего и не перечесть. Компилятор Promela (язык, используемый Spin) и
верификатор (Protocol ANalyser, pan в терминологии Spin) имеют множество ключей,
управляющих различными аспектами работы (режим проверки, степень детализации вывода,
лимит памяти и так далее), так же имеется несколько GUI оболочек. Одним словом, если вам
понадобится что-то особенное, скорее всего, это уже есть в Spin.

Сам процесс работы со Spin схож с RRD - описывается тест на специальном языке Promela (a
PRocess MEta LAnguage), далее компилируете его, на выходе получается исходный файл на языке
С, который надо скомпилировать С компилятором, что бы получить верификатор. Далее
запускаете верификатор, и при обнаружении ошибки он создаёт файл с подробным описанием
ошибки и истории выполнения. Потом из этого файла можно сгенерировать Postscript файл для
просмотра, или использовать для "проигрывания" истории выполнения. Как видно процесс
работы со Spin несколько сложнее, чем с RRD, ну что ж, статус обязывает :).

Возникает закономерный вопрос - чем же меня не устроил Spin? Во-первых, это специальный язык
Promela для описания тестов; с одной стороны это кажется не таким уж и принципиальным
моментом, но с другой стороны я иногда ловлю себя на том, что мне лень делать даже то
минимальное инструментирование кода, которое требуется для RRD. Да и переписывая
программу вручную на другой язык, мы рискуем протестировать не совсем то, что хотели. Во-
вторых, это последовательно согласованная (sequentially consistent) модель памяти; тут уже
ничего не сказать в защиту Spin - поддержка свободного доступа к памяти ("расслабленной
модели памяти") просто необходима для верификатора алгоритмов синхронизации. В-третьих, это
отсутствие встроенной поддержки для таких специфических вещей как вызовы Win32 API
WaitForMultipleObjects() или SignalObjectAndWait(), или ложные пробуждения на condition variable
POSIX, или ожидания с таймаутами, и так далее. Совокупность этих факторов в итоге заставила
меня отвернуться от Spin.

Тем не менее, ещё раз подчеркну, что инструмент очень и очень достойный. Основной сайт
проекта - http://spinroot.com/ .


Вы можете привести примеры кода, чтобы нагляднее пояснить
принципы работы RRD и его отличие от других инструментов?
Вот простой пример, в котором реализуется взаимное исключение на основе спин-мьютекса
(первый пример я приведу в синтаксисе C++09, а второй в синтаксисе RRD, что бы показать
различия):

std::atomic<int> mutex;
int data;

void thread1()

{

    // простой спин-мьютекс

    while (mutex.exchange(1, std::memory_order_acquire))

     std::this_thread::yield();

    data = 1;

    mutex.store(0, std::memory_order_release);

}

void thread2()

{

    // простой спин-мьютекс

    while (mutex.exchange(1, std::memory_order_acquire))

     std::this_thread::yield();

    data = 2;

    mutex.store(0, std::memory_order_relaxed);

}

В этом примере содержится так называемая гонка второго типа (data race type 2). Гонки типа 2
характеризуются тем, что конфликтующие доступы к проблемной переменной не являются
смежными ни в одном чередовании потоков; тем не менее, они конфликтуют из-за возможного
переупорядочивания обращений к памяти при свободном доступе. RRD обнаружит эту гонку и
покажет в результирующей истории исполнения какие именно переупорядочивания имели место.

Вот несколько более сложный пример - lock-free stack (уже записанный в синтаксисе RRD;
основное пространство имён, используемое RRD - "rl", так же обратите внимание на требуемое
инструментирование кода в виде "($)"):

struct node

{

    rl::atomic<node*> next;

    rl::var<void*> data;

};

struct stack

{
rl::atomic<node*> head;

};

void push(stack* s, void* data)

{

    node* n = RL_NEW(node);

    n->data($) = data;

    node* next = s->head($).load(rl::memory_order_relaxed);

    for (;;)

    {

        n->next($).store(next, rl::memory_order_relaxed);

        if (s->head($).compare_exchange_weak(

               next, n, rl::memory_order_release))

         break;

    }

}

void* pop(stack* s)

{

    node* n = s->head($).load(rl::memory_order_relaxed);

    for (;;)

    {

        if (0 == n)

         return 0;

        node* next = n->next($).load(rl::memory_order_relaxed);

        if (s->head($).compare_exchange_weak(

               n, next, rl::memory_order_acquire))

         break;

    }

    void* data = n->data($);

    RL_DELETE(n);

    return data;
}

И вот юнит-тест для RRD:

// шаблонный параметр "2" задаёт кол-во потоков в тесте

struct test : rl::test_suite<test, 2>

{

    stack s;



    // выполняется в одном потоке

    // перед исполнением основной функции потоков

    void before()

    {

        s.head($) = 0;

    }

    // основная функция потоков

    void thread(unsigned /*thread_index*/)

    {

        push(&s, (void*)1);

        void* data = pop(&s);

        RL_ASSERT(data == (void*)1);

    }

};

int main()

{

    rl::simulate<test>();

}

Если мы запустим программу, то увидим следующий вывод (я убрал историю выполнения
отдельных потоков; первая цифра в строчке является глобальным порядковым номером
операции - для сопоставления с историей выполнения отдельных потоков, вторая цифра - номер
потока):

struct test

ACCESS TO FREED MEMORY (access to freed memory)
iteration: 2

execution history:

[0] 1: [BEFORE BEGIN]

[1] 1: <0023DEA0> atomic store, value=00000000,

(prev value=00000000), order=seq_cst, in test::before, main.cpp(70)

[2] 1: [BEFORE END]

[3] 1: memory allocation: addr=0023CB78, size=52,

in push, main.cpp(34)

[4] 1: <0023CB9C> store, value=00000001, in push, main.cpp(35)

[5] 1: <0023DEA0> atomic load, value=00000000, order=relaxed,

in push, main.cpp(36)

[6] 0: memory allocation: addr=0023CE80, size=52,

in push, main.cpp(34)

[7] 0: <0023CEA4> store, value=00000001, in push, main.cpp(35)

[8] 1: <0023CB78> atomic store, value=00000000, (prev value=00000000),

order=relaxed, in push, main.cpp(39)

[9] 0: <0023DEA0> atomic load, value=00000000, order=relaxed,

in push, main.cpp(36)

[10] 0: <0023CE80> atomic store, value=00000000,

(prev value=00000000), order=relaxed, in push, main.cpp(39)

[11] 1: <0023DEA0> CAS fail [SPURIOUSLY] orig=00000000,

cmp=00000000, xchg=0023CB78, order=release, in push, main.cpp(40)

[12] 0: <0023DEA0> CAS succ orig=00000000, cmp=00000000,

xchg=0023CE80, order=release, in push, main.cpp(40)

[13] 1: <0023CB78> atomic store, value=00000000,

(prev value=00000000), order=relaxed, in push, main.cpp(39)

[14] 0: <0023DEA0> atomic load, value=0023CE80, order=relaxed,

in pop, main.cpp(47)

[15] 1: <0023DEA0> CAS fail orig=0023CE80, cmp=00000000,

xchg=0023CB78, order=release, in push, main.cpp(40)
[16] 1: <0023CB78> atomic store, value=0023CE80,

(prev value=00000000), order=relaxed, in push, main.cpp(39)

[17] 0: <0023CE80> atomic load, value=00000000, order=relaxed,

in pop, main.cpp(52)

[18] 1: <0023DEA0> CAS succ orig=0023CE80, cmp=0023CE80,

xchg=0023CB78, order=release, in push, main.cpp(40)

[19] 1: <0023DEA0> atomic load, value=0023CB78, order=relaxed,

in pop, main.cpp(47)

[20] 0: <0023DEA0> CAS fail orig=0023CB78, cmp=0023CE80,

xchg=00000000, order=acquire, in pop, main.cpp(53)

[21] 1: <0023CB78> atomic load, value=0023CE80, order=relaxed,

in pop, main.cpp(52)

[22] 1: <0023DEA0> CAS succ orig=0023CB78, cmp=0023CB78,

xchg=0023CE80, order=acquire, in pop, main.cpp(53)

[23] 1: <0023CB9C> load, value=00000001, in pop, main.cpp(56)

[24] 1: memory deallocation: addr=0023CB78, in pop, main.cpp(57)

[25] 0: ACCESS TO FREED MEMORY (access to freed memory),

in pop, main.cpp(52)

Из вывода мы видим, что при проверке второго чередования потоков RRD обнаружил обращение
к освобожденной памяти. Из анализа истории можно понять, что поток 1 снимает элемент со
стека и освобождает его, после этого поток 0 обращается к этому элементу.


Какое Ваше мнение о новом инструменте VivaMP? Насколько Вы
считаете его сейчас актуальным, ведь технология OpenMP пока
используется достаточно малым количеством разработчиков?
Я думаю, что тут Вы немного лукавите, говоря, что OpenMP используется малым количеством
разработчиком. Конечно, всё относительно; но я думаю, что буду недалек от истины, сказав, что
OpenMP - самая распространённая в промышленном коде библиотека поддержки параллелизма.
Во-первых, это - относительно старое и проверенное средство, поддерживаемое множеством
коммерческих и некоммерческих организаций, с множеством независимых реализаций. Во-
вторых, оно достаточно простое и хорошо решает свою задачу.

Ну и естественно я, как разработчик собственного средства верификации многопоточного кода,
считаю такие инструменты очень актуальными и необходимыми; особенно сейчас, когда у
каждого из нас на рабочем столе стоит компьютер с многоядерным процессором. Исходя из этих
двух вещей, VivaMP - просто незаменимое средство для начинающих в области параллельного
программирования разработчиков. Но VivaMP будет так же полезен и более опытным
разработчикам, так как никто не застрахован как от "глупых" ошибок (невнимательность, copy-
paste), так и от "умных". А VivaMP всегда будет "прикрывать тыл" своей беспристрастностью и
вычислительной мощью. Я знаю не мало примеров, когда многопоточный код, разработанный в
том числе и экспертами, и просмотренный не одной парой глаз, работал годами, но потом в нём
всё же обнаруживались серьёзные ошибки, которые приводили к зависаниям и падениям.
Значительная часть этих ошибок была или могла бы быть обнаружена средствами верификации,
такими как VivaMP.

Касательно технической стороны вопроса, VivaMP - это средство статической верификации. И что
мне очень нравится в статической верификации так это то, что не нужно писать юнит-тесты;
инструмент проверяет целевой код сам по себе. И вопрос даже не столько в необходимости
написать некоторый объём дополнительного кода, сколько в том, что это - опять же человеческий
фактор. Разработчик должен определить, какие именно тесты необходимы, как именно они
должны работать и так далее; и качество проверки напрямую будет зависеть от качества юнит-
тестов. При использовании VivaMP такой проблемы нет, есть только проверяемый код и
инструмент. Я считаю, что это очень сильное свойство.


Вы проявили интерес к открытой библиотеки анализа кода
VivaCore, созданной нашей компании ООО "Системы программной
верификации". С чем это связано и может ли библиотека помочь в
усовершенствовании RRD?
Идея была в устранении необходимости ручного инструментирования кода. Т.е. написать
собственный препроцессор кода на основе библиотеки VivaCore, что бы он вставлял в нужные
места все эти пресловутые "($)", а пользователь мог тестировать непосредственно свой "боевой"
код. Однако после предпроектных исследований выяснилось, что это потребует затрат достаточно
существенных ресурсов, поэтому от этой идеи, к сожалению, пришлось отказаться.


Как дальше Вы планируете развивать RRD?
Планов у меня всегда много :). На сайте RRD можно видеть TODO/Feature List, в котором я
отражаю свои планы и идеи касательно дальнейшего развития RRD. Из наиболее существенных и
интересных доработок можно отметить поддержку локального хранилища потоков (TSS/TLS) с
обёртками для POSIX и Win32, поддержку UNIX сигналов и различных типов аппаратных
прерываний, оптимизация алгоритма полного перебора состояний программы (partial-order
reductions) и распараллеливание работы библиотеки, периодическое сохранение состояния в
контрольных точках, определение "мёртвого" (не тестируемого) кода, моделирование
характеристик программы, касающихся производительности и масштабируемости. Однако в
данный момент развитие библиотеки, так сказать, demand-driven, т.е. движется нуждами
пользователей. Поэтому буду рад услышать отзывы, мысли и идеи читателей по этому поводу.


Что бы вы хотели сказать в заключение тем нашим читателям,
которые начинают осваивать параллельные технологии?
Про параллельные технологии можно сказать всё то же, что и про любую другую новую
технологию - больше экспериментируйте; пробуйте решать простые задачи - смотрите что
получается, а что нет, пробуйте ещё; выдвигайте гипотезы - проверяйте их, выдвигайте новые
гипотезы и так далее. Только практика и обратная связь может сделать Вас - профессионалом. Ну
и, конечно, "не брезгайте" средствами автоматической верификации кода, это как эксперт всегда
стоящий за спиной и приглядывающий за вами. Естественно можно обойтись и без таких средств,
ну уж как минимум они сэкономят вам массу времени.


Большое спасибо за интервью, интересные и содержательные
ответы.
Спасибо. Желаю Вам и нашим читателям успехов в их разработках.


Заключение
Еще раз хотим поблагодарить Дмитрия за интересную беседу и рассказ об инструментах
верификации параллельных приложений. В конце статьи в библиографическом списке читатели
могут познакомиться со списком ресурсов посвященных RRD и ряду других инструментов схожей
направленности.


Библиографический список
   1. Anthony Williams. Peterson's lock with C++0x atomics. http://www.viva64.com/go.php?url=192
   2. Q&A with a TBB Junkie. http://www.viva64.com/go.php?url=193
   3. Relacy Race Detector. http://www.viva64.com/go.php?url=194
   4. Scalable Synchronization Algorithms. http://www.viva64.com/go.php?url=195
   5. Spin - Formal Verification. http://www.viva64.com/go.php?url=196
   6. Евгений Рыжков. VivaMP - инструмент для OpenMP. http://www.viva64.com/art-3-1-
      1671511269.html
   7. Андрей Карпов. Тестирование параллельных программ. http://www.viva64.com/art-3-1-
      65331121.html.
   8. Открытая библиотека VivaCore для разбора и анализа Си/Си++ кода.
      http://www.viva64.com/ru/vivacore-library/.

Mais conteúdo relacionado

Mais procurados

Тестирование параллельных программ
Тестирование параллельных программТестирование параллельных программ
Тестирование параллельных программTatyanazaxarova
 
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.Igor Shkulipa
 
Отладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программОтладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программTatyanazaxarova
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Sergey Vasilyev
 
64-битная версия Loki
64-битная версия Loki64-битная версия Loki
64-битная версия LokiTatyanazaxarova
 
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Andrey Karpov
 
ук 03.007.02 2011
ук 03.007.02 2011ук 03.007.02 2011
ук 03.007.02 2011etyumentcev
 
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...yaevents
 
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interaction
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interactionSqa.days.2010.beskov.system.analyst.and.test.engineers.interaction
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interactionAlexei Lupan
 
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Tatyanazaxarova
 
Benefits of unit-testing and inversion of controll
Benefits of unit-testing and inversion of controllBenefits of unit-testing and inversion of controll
Benefits of unit-testing and inversion of controllMykyta Hopkalo
 
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Tatyanazaxarova
 
C# Desktop. Занятие 17.
C# Desktop. Занятие 17.C# Desktop. Занятие 17.
C# Desktop. Занятие 17.Igor Shkulipa
 
Платформа SmartActors
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActorsetyumentcev
 
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QAFest
 
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...ITMO University
 

Mais procurados (20)

Тестирование параллельных программ
Тестирование параллельных программТестирование параллельных программ
Тестирование параллельных программ
 
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.
 
Отладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программОтладка и оптимизация многопоточных OpenMP-программ
Отладка и оптимизация многопоточных OpenMP-программ
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...
 
64-битная версия Loki
64-битная версия Loki64-битная версия Loki
64-битная версия Loki
 
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Реклама PVS-Studio - статический анализ кода на языке Си и Си++
Реклама PVS-Studio - статический анализ кода на языке Си и Си++
 
ук 03.007.02 2011
ук 03.007.02 2011ук 03.007.02 2011
ук 03.007.02 2011
 
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
 
TAP
TAPTAP
TAP
 
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interaction
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interactionSqa.days.2010.beskov.system.analyst.and.test.engineers.interaction
Sqa.days.2010.beskov.system.analyst.and.test.engineers.interaction
 
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
 
Benefits of unit-testing and inversion of controll
Benefits of unit-testing and inversion of controllBenefits of unit-testing and inversion of controll
Benefits of unit-testing and inversion of controll
 
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
 
C# Desktop. Занятие 17.
C# Desktop. Занятие 17.C# Desktop. Занятие 17.
C# Desktop. Занятие 17.
 
BDD
BDDBDD
BDD
 
Платформа SmartActors
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActors
 
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
 
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...
 
Step 1
Step 1Step 1
Step 1
 

Destaque

Destaque (6)

User Manual X01HT Softbank
User Manual X01HT SoftbankUser Manual X01HT Softbank
User Manual X01HT Softbank
 
BrandSpotter (english description)
BrandSpotter (english description)BrandSpotter (english description)
BrandSpotter (english description)
 
Boardwalk Global Sustainability 100 Index
Boardwalk Global Sustainability 100 IndexBoardwalk Global Sustainability 100 Index
Boardwalk Global Sustainability 100 Index
 
Smbr buzzversusvendas-100624101326-phpapp02
Smbr buzzversusvendas-100624101326-phpapp02Smbr buzzversusvendas-100624101326-phpapp02
Smbr buzzversusvendas-100624101326-phpapp02
 
krakatauposco
krakatauposcokrakatauposco
krakatauposco
 
Copia 2 de nicolás va a la peluquería
Copia  2  de nicolás va a la peluqueríaCopia  2  de nicolás va a la peluquería
Copia 2 de nicolás va a la peluquería
 

Semelhante a Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD)

Lecture1: Introduction to Parallel Computing
Lecture1: Introduction to  Parallel ComputingLecture1: Introduction to  Parallel Computing
Lecture1: Introduction to Parallel ComputingAndrii Rodionov
 
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокTatyanazaxarova
 
Как спроектировать хороший API и почему это так важно
Как спроектировать хороший API и почему это так важноКак спроектировать хороший API и почему это так важно
Как спроектировать хороший API и почему это так важноBubon Makabra
 
JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1sgdread
 
Проблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийПроблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийTatyanazaxarova
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3Computer Science Club
 
Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Maxim Shulga
 
Надежный тест-дизайн
Надежный тест-дизайнНадежный тест-дизайн
Надежный тест-дизайнSQALab
 
Применение статического анализа кода в преподавании и в разработке свободного ПО
Применение статического анализа кода в преподавании и в разработке свободного ПОПрименение статического анализа кода в преподавании и в разработке свободного ПО
Применение статического анализа кода в преподавании и в разработке свободного ПОAndrey Karpov
 
Повышаем и следим за качеством PHP кода
Повышаем и следим за качеством PHP кодаПовышаем и следим за качеством PHP кода
Повышаем и следим за качеством PHP кодаAleksandr Makhomet
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияRuslan Shevchenko
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDKrivoy Rog IT Community
 
Использование комбинаторного тестирования для мобильных приложений
Использование комбинаторного тестирования для мобильных приложенийИспользование комбинаторного тестирования для мобильных приложений
Использование комбинаторного тестирования для мобильных приложенийSQALab
 
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The Grinder
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The GrinderИлья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The Grinder
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The GrinderSQALab
 
Mva stf module 1 - rus
Mva stf module 1 - rusMva stf module 1 - rus
Mva stf module 1 - rusMaxim Shaptala
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeTatyanazaxarova
 
Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"Fwdays
 

Semelhante a Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD) (20)

Sonar quality
Sonar qualitySonar quality
Sonar quality
 
Team workflow
Team workflowTeam workflow
Team workflow
 
Lecture1: Introduction to Parallel Computing
Lecture1: Introduction to  Parallel ComputingLecture1: Introduction to  Parallel Computing
Lecture1: Introduction to Parallel Computing
 
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибок
 
Как спроектировать хороший API и почему это так важно
Как спроектировать хороший API и почему это так важноКак спроектировать хороший API и почему это так важно
Как спроектировать хороший API и почему это так важно
 
JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1
 
Проблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийПроблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложений
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3
 
Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы
 
Надежный тест-дизайн
Надежный тест-дизайнНадежный тест-дизайн
Надежный тест-дизайн
 
Применение статического анализа кода в преподавании и в разработке свободного ПО
Применение статического анализа кода в преподавании и в разработке свободного ПОПрименение статического анализа кода в преподавании и в разработке свободного ПО
Применение статического анализа кода в преподавании и в разработке свободного ПО
 
PVS-Studio vs Chromium
PVS-Studio vs ChromiumPVS-Studio vs Chromium
PVS-Studio vs Chromium
 
Повышаем и следим за качеством PHP кода
Повышаем и следим за качеством PHP кодаПовышаем и следим за качеством PHP кода
Повышаем и следим за качеством PHP кода
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестирования
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
 
Использование комбинаторного тестирования для мобильных приложений
Использование комбинаторного тестирования для мобильных приложенийИспользование комбинаторного тестирования для мобильных приложений
Использование комбинаторного тестирования для мобильных приложений
 
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The Grinder
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The GrinderИлья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The Grinder
Илья Евлампиев - Нагрузочное тестирование веб-приложений с помощью The Grinder
 
Mva stf module 1 - rus
Mva stf module 1 - rusMva stf module 1 - rus
Mva stf module 1 - rus
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"
 

Mais de Tatyanazaxarova

Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияTatyanazaxarova
 
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программTatyanazaxarova
 
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокTatyanazaxarova
 
Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиTatyanazaxarova
 
Урок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурУрок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурTatyanazaxarova
 
Урок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхУрок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхTatyanazaxarova
 
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияTatyanazaxarova
 
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиTatyanazaxarova
 
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаTatyanazaxarova
 
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхTatyanazaxarova
 
Урок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейУрок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейTatyanazaxarova
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаTatyanazaxarova
 
Урок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаУрок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаTatyanazaxarova
 
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовTatyanazaxarova
 
Урок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаУрок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаTatyanazaxarova
 
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеTatyanazaxarova
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияTatyanazaxarova
 
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииTatyanazaxarova
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийTatyanazaxarova
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кодаTatyanazaxarova
 

Mais de Tatyanazaxarova (20)

Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окружения
 
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программ
 
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
 
Урок 24. Фантомные ошибки
Урок 24. Фантомные ошибкиУрок 24. Фантомные ошибки
Урок 24. Фантомные ошибки
 
Урок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структурУрок 23. Паттерн 15. Рост размеров структур
Урок 23. Паттерн 15. Рост размеров структур
 
Урок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данныхУрок 21. Паттерн 13. Выравнивание данных
Урок 21. Паттерн 13. Выравнивание данных
 
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. Исключения
 
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен данными
 
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметика
 
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединениях
 
Урок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателейУрок 15. Паттерн 7. Упаковка указателей
Урок 15. Паттерн 7. Упаковка указателей
 
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметика
 
Урок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвигаУрок 11. Паттерн 3. Операции сдвига
Урок 11. Паттерн 3. Операции сдвига
 
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
 
Урок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числаУрок 9. Паттерн 1. Магические числа
Урок 9. Паттерн 1. Магические числа
 
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном коде
 
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложения
 
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурации
 
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
 
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кода
 

Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD)

  • 1. Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD) Автор: Андрей Карпов Дата: 06.04.2009 Аннотация Интервью с Дмитрием Вьюковым - автором инструмента Relacy Race Detector (RRD) для верификации параллельных приложений. В статье вы узнаете об истории создания RRD, его основных возможностях, а также о некоторых других аналогичных инструментах и их отличии от RRD. Введение Вашему вниманию предлагается интервью с автором верификатора Relacy Race Detector (RRD) для тестирования многопоточных алгоритмов. В интервью обсуждаются перспективы использования RRD и других инструментов для проверки параллельных приложений и смежные темы. Вопросы задает (вопросы будут выделены жирным текстом): Карпов Андрей Николаевич. Один из основателей компании "Системы программной верификации", занимается разработкой инструментов для статического анализа исходного кода. Участвует в развитии инструментов Viva64 и VivaMP для тестирования 64-битных и параллельных приложений. Поддерживает открытую библиотеку VivaCore, предназначенную для разбора (парсинга) Си/Си++ кода. На вопросы отвечает: Вьюков Дмитрий Сергеевич. Разработчик высокопроизводительного программного обеспечения на Си/Си++ в области клиент/серверных систем и сетевых серверов. В свободное время увлекается разработкой инновационных алгоритмов синхронизации, разработкой моделей программирования для многоядерных процессоров и систем верификации многопоточного кода. Автор инструмента Relacy Race Detector (RRD). Текст интервью Здравствуйте, Дмитрий. Расскажите немного о себе, чем занимаетесь и в каких проектах участвуете? В меру своих сил я занимаюсь всем, что связано с многопоточностью и параллелизмом: масштабируемыми алгоритмами синхронизации, моделями программирования для многоядерных процессоров, верификацией многопоточного кода и так далее. Свои разработки
  • 2. касательно алгоритмов синхронизации я публикую в группе Scalable Synchronization Algorithms. Так же я разработал и поддерживаю инструмент верификации многопоточного кода Relacy Race Detector (RRD). Что подтолкнуло Вас к созданию верификатора Relacy Race Detector? RRD появился достаточно спонтанно. Предпосылок для его создания было три. Первая - я занимаюсь разработкой алгоритмов синхронизации, а тестирование и локализация ошибок в них - очень и очень серьёзная проблема: ошибки проявляются очень редко или вообще не проявляются на некоторых компьютерах (допустим на компьютерах с менее чем 4-мя процессорами, или на компьютерах с некоторой версией операционной системы). А если ошибка всё-таки регулярно проявляется, то часто бывает очень сложно понять истинную первопричину ошибки (в какой момент и что именно начинает идти "не так"). Это породило мысль, что неплохо было бы иметь какие-то "инструменты" для решения проблемы. Вторая предпосылка - за время работы с алгоритмами синхронизации накопился некоторый багаж приёмов, которые я применял для тестирования и локализации ошибок. Один из основных - это вставка в код программы большого количества примерно таких строчек: if ((rand() % 1000) == 0) Sleep (rand() % 10); и последующее стресс-тестирование работы программы. Этот приём позволяет добиться выполнения значительно большего количества различных чередований (interleaving) потоков. Собственно это, по большому счёту, и является основным принципом работы RRD. Третьей предпосылкой явилось то, что в какой-то момент я, наконец, понял, как можно собрать все мои приёмы в автоматический инструмент тестирования, как можно простым способом проводить необходимое инструментирование программы, и как при этом можно обеспечить высокую эффективность работы инструмента. Дальше было дело техники - первый рабочий прототип (который реально обнаружил одну специально внесённую ошибку в простой алгоритм) появился в тот же день ближе к ночи. Хотя, конечно, доведение RRD до более-менее пригодного для реальной работы вида заняло значительно больше времени. Расскажите, пожалуйста, о RRD более подробно. Какие принципы и алгоритмы лежат в его основе? В каких областях его применение наиболее перспективно? RRD является средством динамической верификации без запоминания состояний. Он предназначен, прежде всего, для тестирования многопоточных алгоритмов (алгоритмов синхронизации, многопоточных структур данных и так далее). Для пользователя работа с RRD выглядит примерно следующим образом. Вначале реализуется тестируемый алгоритм. Реализация может быть выражена через примитивы синхронизации C++09, POSIX threads (pthread), Win32 API, C#/.NET, Java. Однако необходимо использовать указанные API не напрямую, а через "обёртки", предоставляемые RRD; синтаксис практически идентичен, однако имеются некоторые отличия. Когда тестируемый алгоритм реализован, необходимо реализовать один или несколько юнит-тестов (unit test) для алгоритма. Далее можно запускать их на исполнение, при
  • 3. этом RRD позаботится об эффективном исполнении тестов, то есть будет проверено как можно больше различных чередований (interleaving) потоков. Во время исполнения каждого чередования RRD будет делать множество различных проверок корректности алгоритма, включая как пользовательские утверждения (asserts) и инварианты (invariants), так и базовые встроенные проверки - гонки (data races), обращения к освобожденной памяти, двойные освобождения памяти, утечки памяти, взаимные блокировки (deadlocks), активные блокировки (livelocks), некорректные использования API (например, рекурсивный захват нерекурсивного мьютекса), и другие. При обнаружении ошибки RRD выведет подробную историю исполнения, которая привела к ошибке. Имея на руках такую историю, локализация ошибки становится делом техники (история содержит такие детали как отклонения от последовательно согласованного (sequentially consistent) порядка, инстансы ABA проблемы, ложные пробуждения на условных переменных (condition variable) и т.д.). Большое количество встроенных проверок и пристрастность, с которой RRD их проводит, позволяют во многих случаях не делать в тесте вообще никаких пользовательских проверок. Например, если мы тестируем reader-writer мьютекс, то достаточно лишь создать несколько потоков, которые будут захватывать мьютекс на чтение и считывать какую-то переменную, и несколько потоков, которые захватывают мьютекс для записи и изменяют эту же переменную. Если алгоритм мьютекса не обеспечивает взаимного исключения, то автоматически будет обнаружена гонка на защищаемой переменной; если алгоритм может входить во взаимную блокировку или активную блокировку, то RRD тоже обнаруживает это автоматически. Однако если мы тестируем очередь типа производитель-потребитель (producer-consumer), и очередь должна обеспечивать FIFO порядок сообщений, то такую проверку придётся запрограммировать вручную. Теперь немного о внутреннем устройстве RRD, и об используемых алгоритмах. RRD инструментирует все обращения к переменным, примитивам синхронизации и API вызовам. Это даёт возможность встроить в них все необходимые проверки, а так же возможность полностью управлять переключением потоков. RRD содержит 3 планировщика потоков (выбор планировщика производится при запуске теста). Самый простой планировщик - это так называемый случайный планировщик (random scheduler), после каждого элементарного действия программы (обращении к переменной, примитиву синхронизации, API вызову) планировщик выбирает случайный поток и переключает управление на него. Этот планировщик хорош для первоначального тестирования алгоритма, т.к. он не даёт исчерпывающей проверки, но зато работает очень быстро. Второй планировщик производит полный систематический перебор всех возможных чередований потоков (full search scheduler), однако его недостаток в очень длительном времени верификации, на практике его целесообразно применять только для небольших тестов. Последний, третий, планировщик самый интересный и полезный - это так называемый планировщик с ограничением на количество переключений потоков (context bound scheduler). Он производит систематический перебор чередования потоков, однако при этом проверяет только чередования, в которых общее количество добровольных переключений потоков не больше некоторого заданного числа. За счёт этого он даёт очень хороший компромисс между качеством проверки и временем работы. Так же следует отметить, что все планировщики являются справедливыми (fair), это даёт возможность тестировать формально не терминирующие алгоритмы, т.е. алгоритмы, содержащие циклы, которые могут повторяться потенциально неограниченное число раз.
  • 4. На каких условиях распространяется RRD? RRD может свободно использоваться для некоммерческой разработки с открытыми исходными кодами, для образовательных целей, для академических разработок с непатентуемыми результатами, а так же для персонального некоммерческого использования. Для всех остальных применений RRD является платным. Хотя возможно рассмотрение частных случаев; например, я имел некоторые предварительные беседы касательно предоставления специальных лицензий для разработки ядра Linux (там есть некоторые скользкие моменты, касающиеся патентованных алгоритмов и коммерциализации), а так же для разработки Intel Threading Building Blocks (который распространяется под двойной лицензией, одна из которых коммерческая). Вы можете порекомендовать какие-то дополнительные ресурсы, связанные с RRD? Где можно скачать RRD? Основной ресурс, посвященный RRD расположен по адресу: http://www.viva64.com/go.php?url=194 Там можно скачать последнюю версию библиотеки, найти некоторые материалы по RRD, а так же задавать вопросы. Дистрибутив RRD включает ряд примеров, которые могут помочь освоить RRD. Вы, наверное, знакомы со многими другими верификаторами параллельных приложений. Действительно ли не один из них не реализует диагностики, которые позволяет производить RRD? В чем их отличие от RRD? Да, конечно, до создания RRD я смотрел на множество средств верификации (Intel Thread Checker, Chord, Zing, Spin, RacerX, CheckFence, Sober, Coverity Thread Analyzer, CHESS, KISS, PreFast, Prefix, FxCop) в надежде найти то, что нужно для моих целей. Однако большинство инструментов рассчитаны, так сказать, на разработчиков конечных прикладных программ, а не на разработчиков алгоритмов синхронизации и библиотек поддержки параллелизма. Ни один из инструментов не даёт того уровня детализации и точности моделирования свободного доступа к памяти (Relaxed Memory Order) [*], который был необходим мне. Образно, если упомянутые средства могут верифицировать программу, использующую OpenMP, то RRD может верифицировать саму реализацию OpenMP. [*] Примечание. Свободный доступ к памяти (Relaxed Memory Order, RMO) - метод работы с памятью, когда процессор использует все средства кэширования и динамического переупорядочения команд, и не пытается обеспечить никаких требований к упорядоченности выборки и сохранению операндов в основной памяти. Иногда такой режим называют "расслабленная модель памяти". Вы назвали множество различных инструментов. Не могли бы Вы вкратце рассказать о них? Многие читатели, вероятно, даже не слышали о большинстве этих инструментов. Сразу оговорюсь, что с большинством инструментов я не знакомился практически (установка, запуск примеров, применение в собственных проектах). Я знакомился с ними поверхностно, так
  • 5. как из общих описаний мне становилось понятно, что это не то, что мне нужно; и дальше знакомиться не имело смысла. Поэтому я, наверное, не смогу рассказать много интересного для конечных пользователей, но тем не менее... Могу рассказать про инструмент Spin, который несколько приближается по свойствам к RRD, и я знаю, что он использовался для верификации некоторых алгоритмов синхронизации для ядра Linux и для Threading Building Blocks. Spin - это, наверное, самый старый и основательный инструмент такого рода, его корни уходят в начало 80-ых годов, по нему написан ряд книг, и, что очень приятно, он активно развивается и по сей день. Spin включает множество вариантов проверки - динамическая проверка с запоминанием состояний, без запоминания, полная проверка модели программы, не полная проверка модели программы (для очень больших программ) и так дадее, всего и не перечесть. Компилятор Promela (язык, используемый Spin) и верификатор (Protocol ANalyser, pan в терминологии Spin) имеют множество ключей, управляющих различными аспектами работы (режим проверки, степень детализации вывода, лимит памяти и так далее), так же имеется несколько GUI оболочек. Одним словом, если вам понадобится что-то особенное, скорее всего, это уже есть в Spin. Сам процесс работы со Spin схож с RRD - описывается тест на специальном языке Promela (a PRocess MEta LAnguage), далее компилируете его, на выходе получается исходный файл на языке С, который надо скомпилировать С компилятором, что бы получить верификатор. Далее запускаете верификатор, и при обнаружении ошибки он создаёт файл с подробным описанием ошибки и истории выполнения. Потом из этого файла можно сгенерировать Postscript файл для просмотра, или использовать для "проигрывания" истории выполнения. Как видно процесс работы со Spin несколько сложнее, чем с RRD, ну что ж, статус обязывает :). Возникает закономерный вопрос - чем же меня не устроил Spin? Во-первых, это специальный язык Promela для описания тестов; с одной стороны это кажется не таким уж и принципиальным моментом, но с другой стороны я иногда ловлю себя на том, что мне лень делать даже то минимальное инструментирование кода, которое требуется для RRD. Да и переписывая программу вручную на другой язык, мы рискуем протестировать не совсем то, что хотели. Во- вторых, это последовательно согласованная (sequentially consistent) модель памяти; тут уже ничего не сказать в защиту Spin - поддержка свободного доступа к памяти ("расслабленной модели памяти") просто необходима для верификатора алгоритмов синхронизации. В-третьих, это отсутствие встроенной поддержки для таких специфических вещей как вызовы Win32 API WaitForMultipleObjects() или SignalObjectAndWait(), или ложные пробуждения на condition variable POSIX, или ожидания с таймаутами, и так далее. Совокупность этих факторов в итоге заставила меня отвернуться от Spin. Тем не менее, ещё раз подчеркну, что инструмент очень и очень достойный. Основной сайт проекта - http://spinroot.com/ . Вы можете привести примеры кода, чтобы нагляднее пояснить принципы работы RRD и его отличие от других инструментов? Вот простой пример, в котором реализуется взаимное исключение на основе спин-мьютекса (первый пример я приведу в синтаксисе C++09, а второй в синтаксисе RRD, что бы показать различия): std::atomic<int> mutex;
  • 6. int data; void thread1() { // простой спин-мьютекс while (mutex.exchange(1, std::memory_order_acquire)) std::this_thread::yield(); data = 1; mutex.store(0, std::memory_order_release); } void thread2() { // простой спин-мьютекс while (mutex.exchange(1, std::memory_order_acquire)) std::this_thread::yield(); data = 2; mutex.store(0, std::memory_order_relaxed); } В этом примере содержится так называемая гонка второго типа (data race type 2). Гонки типа 2 характеризуются тем, что конфликтующие доступы к проблемной переменной не являются смежными ни в одном чередовании потоков; тем не менее, они конфликтуют из-за возможного переупорядочивания обращений к памяти при свободном доступе. RRD обнаружит эту гонку и покажет в результирующей истории исполнения какие именно переупорядочивания имели место. Вот несколько более сложный пример - lock-free stack (уже записанный в синтаксисе RRD; основное пространство имён, используемое RRD - "rl", так же обратите внимание на требуемое инструментирование кода в виде "($)"): struct node { rl::atomic<node*> next; rl::var<void*> data; }; struct stack {
  • 7. rl::atomic<node*> head; }; void push(stack* s, void* data) { node* n = RL_NEW(node); n->data($) = data; node* next = s->head($).load(rl::memory_order_relaxed); for (;;) { n->next($).store(next, rl::memory_order_relaxed); if (s->head($).compare_exchange_weak( next, n, rl::memory_order_release)) break; } } void* pop(stack* s) { node* n = s->head($).load(rl::memory_order_relaxed); for (;;) { if (0 == n) return 0; node* next = n->next($).load(rl::memory_order_relaxed); if (s->head($).compare_exchange_weak( n, next, rl::memory_order_acquire)) break; } void* data = n->data($); RL_DELETE(n); return data;
  • 8. } И вот юнит-тест для RRD: // шаблонный параметр "2" задаёт кол-во потоков в тесте struct test : rl::test_suite<test, 2> { stack s; // выполняется в одном потоке // перед исполнением основной функции потоков void before() { s.head($) = 0; } // основная функция потоков void thread(unsigned /*thread_index*/) { push(&s, (void*)1); void* data = pop(&s); RL_ASSERT(data == (void*)1); } }; int main() { rl::simulate<test>(); } Если мы запустим программу, то увидим следующий вывод (я убрал историю выполнения отдельных потоков; первая цифра в строчке является глобальным порядковым номером операции - для сопоставления с историей выполнения отдельных потоков, вторая цифра - номер потока): struct test ACCESS TO FREED MEMORY (access to freed memory)
  • 9. iteration: 2 execution history: [0] 1: [BEFORE BEGIN] [1] 1: <0023DEA0> atomic store, value=00000000, (prev value=00000000), order=seq_cst, in test::before, main.cpp(70) [2] 1: [BEFORE END] [3] 1: memory allocation: addr=0023CB78, size=52, in push, main.cpp(34) [4] 1: <0023CB9C> store, value=00000001, in push, main.cpp(35) [5] 1: <0023DEA0> atomic load, value=00000000, order=relaxed, in push, main.cpp(36) [6] 0: memory allocation: addr=0023CE80, size=52, in push, main.cpp(34) [7] 0: <0023CEA4> store, value=00000001, in push, main.cpp(35) [8] 1: <0023CB78> atomic store, value=00000000, (prev value=00000000), order=relaxed, in push, main.cpp(39) [9] 0: <0023DEA0> atomic load, value=00000000, order=relaxed, in push, main.cpp(36) [10] 0: <0023CE80> atomic store, value=00000000, (prev value=00000000), order=relaxed, in push, main.cpp(39) [11] 1: <0023DEA0> CAS fail [SPURIOUSLY] orig=00000000, cmp=00000000, xchg=0023CB78, order=release, in push, main.cpp(40) [12] 0: <0023DEA0> CAS succ orig=00000000, cmp=00000000, xchg=0023CE80, order=release, in push, main.cpp(40) [13] 1: <0023CB78> atomic store, value=00000000, (prev value=00000000), order=relaxed, in push, main.cpp(39) [14] 0: <0023DEA0> atomic load, value=0023CE80, order=relaxed, in pop, main.cpp(47) [15] 1: <0023DEA0> CAS fail orig=0023CE80, cmp=00000000, xchg=0023CB78, order=release, in push, main.cpp(40)
  • 10. [16] 1: <0023CB78> atomic store, value=0023CE80, (prev value=00000000), order=relaxed, in push, main.cpp(39) [17] 0: <0023CE80> atomic load, value=00000000, order=relaxed, in pop, main.cpp(52) [18] 1: <0023DEA0> CAS succ orig=0023CE80, cmp=0023CE80, xchg=0023CB78, order=release, in push, main.cpp(40) [19] 1: <0023DEA0> atomic load, value=0023CB78, order=relaxed, in pop, main.cpp(47) [20] 0: <0023DEA0> CAS fail orig=0023CB78, cmp=0023CE80, xchg=00000000, order=acquire, in pop, main.cpp(53) [21] 1: <0023CB78> atomic load, value=0023CE80, order=relaxed, in pop, main.cpp(52) [22] 1: <0023DEA0> CAS succ orig=0023CB78, cmp=0023CB78, xchg=0023CE80, order=acquire, in pop, main.cpp(53) [23] 1: <0023CB9C> load, value=00000001, in pop, main.cpp(56) [24] 1: memory deallocation: addr=0023CB78, in pop, main.cpp(57) [25] 0: ACCESS TO FREED MEMORY (access to freed memory), in pop, main.cpp(52) Из вывода мы видим, что при проверке второго чередования потоков RRD обнаружил обращение к освобожденной памяти. Из анализа истории можно понять, что поток 1 снимает элемент со стека и освобождает его, после этого поток 0 обращается к этому элементу. Какое Ваше мнение о новом инструменте VivaMP? Насколько Вы считаете его сейчас актуальным, ведь технология OpenMP пока используется достаточно малым количеством разработчиков? Я думаю, что тут Вы немного лукавите, говоря, что OpenMP используется малым количеством разработчиком. Конечно, всё относительно; но я думаю, что буду недалек от истины, сказав, что OpenMP - самая распространённая в промышленном коде библиотека поддержки параллелизма. Во-первых, это - относительно старое и проверенное средство, поддерживаемое множеством коммерческих и некоммерческих организаций, с множеством независимых реализаций. Во- вторых, оно достаточно простое и хорошо решает свою задачу. Ну и естественно я, как разработчик собственного средства верификации многопоточного кода, считаю такие инструменты очень актуальными и необходимыми; особенно сейчас, когда у каждого из нас на рабочем столе стоит компьютер с многоядерным процессором. Исходя из этих двух вещей, VivaMP - просто незаменимое средство для начинающих в области параллельного
  • 11. программирования разработчиков. Но VivaMP будет так же полезен и более опытным разработчикам, так как никто не застрахован как от "глупых" ошибок (невнимательность, copy- paste), так и от "умных". А VivaMP всегда будет "прикрывать тыл" своей беспристрастностью и вычислительной мощью. Я знаю не мало примеров, когда многопоточный код, разработанный в том числе и экспертами, и просмотренный не одной парой глаз, работал годами, но потом в нём всё же обнаруживались серьёзные ошибки, которые приводили к зависаниям и падениям. Значительная часть этих ошибок была или могла бы быть обнаружена средствами верификации, такими как VivaMP. Касательно технической стороны вопроса, VivaMP - это средство статической верификации. И что мне очень нравится в статической верификации так это то, что не нужно писать юнит-тесты; инструмент проверяет целевой код сам по себе. И вопрос даже не столько в необходимости написать некоторый объём дополнительного кода, сколько в том, что это - опять же человеческий фактор. Разработчик должен определить, какие именно тесты необходимы, как именно они должны работать и так далее; и качество проверки напрямую будет зависеть от качества юнит- тестов. При использовании VivaMP такой проблемы нет, есть только проверяемый код и инструмент. Я считаю, что это очень сильное свойство. Вы проявили интерес к открытой библиотеки анализа кода VivaCore, созданной нашей компании ООО "Системы программной верификации". С чем это связано и может ли библиотека помочь в усовершенствовании RRD? Идея была в устранении необходимости ручного инструментирования кода. Т.е. написать собственный препроцессор кода на основе библиотеки VivaCore, что бы он вставлял в нужные места все эти пресловутые "($)", а пользователь мог тестировать непосредственно свой "боевой" код. Однако после предпроектных исследований выяснилось, что это потребует затрат достаточно существенных ресурсов, поэтому от этой идеи, к сожалению, пришлось отказаться. Как дальше Вы планируете развивать RRD? Планов у меня всегда много :). На сайте RRD можно видеть TODO/Feature List, в котором я отражаю свои планы и идеи касательно дальнейшего развития RRD. Из наиболее существенных и интересных доработок можно отметить поддержку локального хранилища потоков (TSS/TLS) с обёртками для POSIX и Win32, поддержку UNIX сигналов и различных типов аппаратных прерываний, оптимизация алгоритма полного перебора состояний программы (partial-order reductions) и распараллеливание работы библиотеки, периодическое сохранение состояния в контрольных точках, определение "мёртвого" (не тестируемого) кода, моделирование характеристик программы, касающихся производительности и масштабируемости. Однако в данный момент развитие библиотеки, так сказать, demand-driven, т.е. движется нуждами пользователей. Поэтому буду рад услышать отзывы, мысли и идеи читателей по этому поводу. Что бы вы хотели сказать в заключение тем нашим читателям, которые начинают осваивать параллельные технологии? Про параллельные технологии можно сказать всё то же, что и про любую другую новую технологию - больше экспериментируйте; пробуйте решать простые задачи - смотрите что
  • 12. получается, а что нет, пробуйте ещё; выдвигайте гипотезы - проверяйте их, выдвигайте новые гипотезы и так далее. Только практика и обратная связь может сделать Вас - профессионалом. Ну и, конечно, "не брезгайте" средствами автоматической верификации кода, это как эксперт всегда стоящий за спиной и приглядывающий за вами. Естественно можно обойтись и без таких средств, ну уж как минимум они сэкономят вам массу времени. Большое спасибо за интервью, интересные и содержательные ответы. Спасибо. Желаю Вам и нашим читателям успехов в их разработках. Заключение Еще раз хотим поблагодарить Дмитрия за интересную беседу и рассказ об инструментах верификации параллельных приложений. В конце статьи в библиографическом списке читатели могут познакомиться со списком ресурсов посвященных RRD и ряду других инструментов схожей направленности. Библиографический список 1. Anthony Williams. Peterson's lock with C++0x atomics. http://www.viva64.com/go.php?url=192 2. Q&A with a TBB Junkie. http://www.viva64.com/go.php?url=193 3. Relacy Race Detector. http://www.viva64.com/go.php?url=194 4. Scalable Synchronization Algorithms. http://www.viva64.com/go.php?url=195 5. Spin - Formal Verification. http://www.viva64.com/go.php?url=196 6. Евгений Рыжков. VivaMP - инструмент для OpenMP. http://www.viva64.com/art-3-1- 1671511269.html 7. Андрей Карпов. Тестирование параллельных программ. http://www.viva64.com/art-3-1- 65331121.html. 8. Открытая библиотека VivaCore для разбора и анализа Си/Си++ кода. http://www.viva64.com/ru/vivacore-library/.