to the top
close form
Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Мирное сосуществование PC-Lint и VivaMP

Мирное сосуществование PC-Lint и VivaMP

23 Фев 2009

Нам задают различные вопросы, связанные с использованием PC-Lint, VivaMP и других статических анализаторов для проверки параллельных программ, спрашивают, являются ли они конкурентами и задают другие схожие вопросы. Видимо это связанно с выходом новой версии PC-Lint 9.0, в которой заявлено о поддержке анализа параллельности (см. PC-lint Manual. Раздел: 12. Multi-thread support). Я решил объединить обсуждения, в которых я участвовал по этому поводу и представить их в виде двух вопросов, на которые я дам развернутые ответы.

Поддержка VivaMP была прекращена в 2014 году. По всем возникшим вопросам вы можете обратиться в нашу поддержку.

Вопрос первый.

Можно ли использовать PC-Lint для проверки параллельных программ?

Этот вопрос часто задают, но, к сожалению, он не удачен. Прямой на него ответ - да. Но люди на самом деле вкладывают в этот вопрос другой смысл - "Можно ли используя PC-Lint найти ошибки в программах, связанных с использованием распараллеливания алгоритмов?". Тогда ответ - нет, если не предпринять специальных действий.

Все дело в том, что статический анализатор не знает, выполняется ли определенный участок кода параллельно и может только строить некоторые предположения. Вот две основные причины такого неведения:

1) Статические анализаторы, как и компиляторы, работают с каждым .cpp файлом отдельно. И поэтому, если в файле A параллельно вызывается функция f() из файла B, то при анализе файла B мы не знаем об этом. Конечно, можно создать статические анализаторы (возможно, такие и есть), которые анализируют все файлы сразу, но это крайне сложная задача. По крайней мере, PC-Lint работает с каждым файлом отдельно.

2) Даже если вызов функции f() находится в том же файле, то все равно не так просто бывает понять, будет ли параллельный вызов или нет. Вызов может сложным образом зависеть от логики алгоритма и входных данных, которыми статический анализатор не обладает.

Возьмем пример функции (приведенный в руководстве к PC-Lint версии 9.0):

void f()
{
  static int n = 0;
  /* ... */
}

Проблема состоит в том, что если функция f() будет вызвана из параллельных потоков, то может возникнуть ошибка инициализации переменной 'n'. Для диагностики данной ситуации, необходимо явно указать анализатору PC-Lint, что функция f() может вызываться параллельно. Для этого необходимо использовать конструкции вида:

//lint -sem(f, thread)

Только тогда, при диагностике кода, вы получите предупреждение: Warning 457: "Thread 'f(void)' has an unprotected write access to variable 'n' which is used by thread 'f(void)" .

На самом деле, высказанное мною ранее утверждение, что, не предпринимая специальных действий, нельзя автоматически диагностировать ошибки в параллельном коде не совсем верно. PC-Lint поддерживает POSIX threads и может, например, автоматически обнаружить ошибки связанные с блокировками, если будут использоваться такие функции, как pthread_mutex_lock() и pthread_mutex_unlock(). Но если механизм параллельности построен не на POSIX threads, то вам опять-таки будет необходимо использовать специальные директивы, чтобы подсказать PC-Lint какие функции приводят к блокировке и разблокировке:

-sem(function-name, thread_lock)

-sem(function-name, thread_unlock)

В этом случае можно обнаружить ошибки в коде, подобному следующему:

//lint -sem( lock, thread_lock )
//lint -sem( unlock, thread_unlock )
extern int g();
void lock(void), unlock(void);
void f()
{
  //-------------
  lock();
  if( g() )
    return; // Warning 454
  unlock();
  //-------------
  if( g() )
  {
    lock();
    unlock();
    unlock(); // Warning 455
    return;
  }
  //-------------
  if( g() )
    lock();
  { // Warning 456
    // do something interesting
  }
}

Еще раз попробую дать заключительный ответ. Анализатор PC-Lint может эффективно находить ошибки связанные с параллельностью, если предварительно сделать ему все необходимые "подсказки". В противном случае он может протестировать параллельный код, считая его последовательным и тем самым не обнаружив в нем ряд ошибок.

Из всего описанного вытекает второй вопрос.

Если анализатор PC-Lint позволяет искать ошибки связанные с параллельностью, то имеет ли смысл использовать VivaMP?

Ответа два:

1) PC-Lint не умеет находить ошибки в программах, построенных на технологии OpenMP.

2) VivaMP специализированный продукт для диагностики параллельных программ, в то время как PC-Lint хороший статический анализатор общего назначения. Еще раз подчеркну: хороший, но общего назначения. Анализ параллельности в нем это всего лишь одна из подсистем. Инструмент VivaMP специально создан для диагностики параллельных программ и обладает большими возможностями в этой области.

Можно заявить, что VivaMP и PC-Lint не являются конкурентами. Они дополняют друг друга. То, что умеет диагностировать VivaMP не умеет делать PC-Lint. То, что умеет делать PC-Lint, не умеет VivaMP. Но постепенно учится :). Поясню это на примерах.

Вновь возьмем пример со статической переменной:

void f()
{
  #pragma omp parallel num_threads(2)
  {
    static int cachedResult = ComputeSomethingSlowly();
    ...
  }
  ...
}

Статическая переменная объявлена внутри параллельной OpenMP секции, что приведет к ошибке инициализации. В данном примере PC-Lint не способен обнаружить ошибку. Мы не можем указать, что функция f() выполняется параллельно, поскольку в данном примере только часть кода функции будет распараллелена. VivaMP же обнаружит ошибку и выдаст сообщение: V1204. Data race risk. Unprotected static variable declaration in a parallel code.

Аналогичная ситуация будет в случае ошибки с блокировкой/разблокировкой. Рассмотрим следующий код:

void foo()
{
  ...
  #pragma omp parallel sections
  {
    #pragma omp section // V1102.
    {
      omp_set_lock(&myLock);
    }
    #pragma omp section // V1102.
    {
      omp_unset_lock(&myLock);
    }
  }
  ...
}

В данном случае есть две OpenMP директивы, которые в двух секциях несимметрично используют функции omp_set_lock и omp_unset_lock. То есть приведенный код содержит две ошибки, о которых и сообщит анализатор VivaMP (V1102. Non-symmetrical use of set/unset functions for the following lock variable(s): myLock).

А вот PC-Lint здесь помочь не сможет. Дело в том, что OpenMP директивы для него ничего не значат, то есть он просто их игнорирует. А следовательно с точки зрения PC-Lint код будет выглядеть так:

//lint -sem(omp_set_lock, thread_lock)
//lint -sem(omp_unset_lock, thread_unlock)
void foo()
{
  ...
  {
    omp_set_lock(&myLock);
  }
  {
    omp_unset_lock(&myLock);
  }
  ...
}

Даже если мы укажем для PC-Lint, что omp_set_lock/omp_unset_lock используется для блокировки/разблокировки, то для него функция foo() в отличие от VivaMP будет корректна. Есть одна блокировка и одна разблокировка. Ошибки нет.

Еще раз повторю, что причина в том, что PC-Lint не анализирует директивы OpenMP заданные с помощью конструкций #pragma, из-за чего логика алгоритма для него представляется по-иному.

Вывод

VivaMP и PC-Lint два хороших инструмента, ориентированных на различные аспекты параллельного программирования, и отлично дополняют друг друга.

Популярные статьи по теме
C++ — язык 2022 года. Почему так, и что с другими языками?

Дата: 20 Янв 2023

Автор: Сергей Васильев

C++ становится языком 2022 года по версии TIOBE, обгоняя Python. Rust, C#, Go и прочие — далеко позади. Странно? Сейчас разберёмся.
PVS-Studio в 2022 году

Дата: 19 Янв 2023

Автор: Полина Алексеева

На дворе январь 2023, а значит, самое время подвести итоги уже прошлого 2022 года. Мы расскажем, чем занимались, и покажем, что нового появилось в анализаторе за это время. Давайте вместе взглянем на…
PVS-Studio: 2 фишки для быстрого старта

Дата: 08 Дек 2022

Автор: Сергей Васильев

В этой заметке расскажу, как легко начать использовать PVS-Studio. Рассмотрим два сценария: когда вы пробуете анализатор впервые и когда внедряете его в проект.
Почему ты делаешь за меня мою работу? Типы людей, которые не пишут в поддержку

Дата: 06 Дек 2022

Автор: Алёна Фоканова

Привлекательное название статьи должно раскрывать то, что будет в ней. Так вот, работа специалистом поддержки клиентов подразумевает появление вопросов к пользователю. Иногда возникает как раз такой:…
Как Apple и другие крупные компании настиг программный баг

Дата: 09 Ноя 2022

Автор: Ульяна Гришина

Сегодня мы отобрали свежие случаи программных ошибок, чтобы вы могли немного отвлечься и, возможно, узнать что-то новенькое. Если вам интересно узнать, как программисту удалось сломать Интернет по вс…

Комментарии (0)

Следующие комментарии next comments
close comment form
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо