Intel Inspector сообщает о гонке данных в моей реализации спин-блокировки

StackOverflow https://stackoverflow.com/questions/1470741

Вопрос

Я сделал очень простую спин-блокировку, используя функции блокировки в Windows, и протестировал ее на двухъядерном процессоре (два потока, которые увеличивают переменную);

Программа вроде работает нормально (каждый раз выдаёт один и тот же результат, чего не бывает при отсутствии синхронизации), но Интел-параллельный инспектор говорит, что существует состояние гонки на значение += j (см. код ниже).Предупреждение исчезает при использовании критических разделов вместо SpinLock.

Правильная ли моя реализация SpinLock или нет?Это действительно странно, потому что все используемые операции являются атомарными и имеют соответствующие барьеры памяти, и это не должно приводить к состояниям гонки.

class SpinLock
{
   int *lockValue;
   SpinLock(int *value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange((volatile LONG*)lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange((volatile LONG*)lockValue, 0); }
};

Тестовая программа:

static const int THREADS = 2;
HANDLE completedEvents[THREADS];
int value = 0;
int lock = 0; // Global.

DWORD WINAPI TestThread(void *param) {
    HANDLE completed = (HANDLE)param;
    SpinLock testLock(&lock);

    for(int i = 0;i < 1000*20; i++) {
        for(int j = 0;j < 10*10; j++) {
            // Add something to the variable.
            testLock.Lock();
            value += j;
            testLock.Unlock();
        }
    }
    SetEvent(completed);
}

int main() {
   for(int i = 0; i < THREADS; i++) {
        completedEvents[i] = CreateEvent(NULL, true, false, NULL);
   }
   for(int i = 0; i < THREADS; i++) {
        DWORD id;
        CreateThread(NULL, 0, TestThread, completedEvents[i], 0, &id);
   }

   WaitForMultipleObjects(THREADS, completedEvents, true, INFINITE);
   cout<<value;
}
Это было полезно?

Решение

Документация Parallel Inspector для гонка данных предлагает использовать критический раздел или мьютекс для исправления скачков в Windows.В нем нет ничего, что указывало бы на то, что Parallel Inspector умеет распознавать любой другой механизм блокировки, который вы можете изобрести.

Инструменты для анализа новых механизмов блокировки, как правило, представляют собой статические инструменты, которые просматривают все возможные пути кода. Документация Parallel Inspector подразумевает, что он выполняет код один раз.

Если вы хотите поэкспериментировать с новыми механизмами блокировки, наиболее распространенным инструментом, который я видел в научной литературе, является Проверка модели спина.Есть также ESP, что может уменьшить пространство состояний, но я не знаю, применялось ли оно к параллельным задачам, а также к мобильное рабочее место который даст анализ, если вы сможете сформулировать свою проблему в пи-исчислении.Intel Parallel Inspector не кажется таким сложным, как эти инструменты, а скорее предназначен для проверки часто возникающих проблем с помощью эвристики.

Другие советы

Для других бедных людей в аналогичной ситуации со мной:Intel ДЕЙСТВИТЕЛЬНО предоставляет набор включений и библиотек для выполнения именно таких задач.Проверьте каталог установки Inspector (в каталоге установки вы увидите \include, \lib32 и \lib64) на наличие этих материалов.Документация по их использованию (по состоянию на июнь 2018 г., хотя Intel не заботится о сохранении согласованности ссылок):

https://software.intel.com/en-us/inspector-user-guide-windows-apis-for-custom-synchronization

Есть 3 функции:

void __itt_sync_acquired(void *addr)
void __itt_sync_releasing(void *addr)
void __itt_sync_destroy(void *addr)

Я почти уверен, что это должно быть реализовано следующим образом:

class SpinLock
{
   long lockValue;
   SpinLock(long value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange(&lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange(&lockValue, 0); }
};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top