Как стать автором
Обновить

Комментарии 8

1) CRITICAL_SECTION

2) "это одна операция, во время которой поток не может быть прерван" звучит так, что будто атомарные переменные скедулер ОС выключают или прерывания отключают... А смысл атомарности же в том, что другие потоки выполнения видят её как одну операцию, разве нет?

верно, операция в общей области памяти называется атомарной, если она завершается в один шаг относительно других потоков, имеющих доступ к этой памяти. Во время выполнения такой операции над переменной, ни один поток не может наблюдать изменение наполовину завершенным. Но сама операция может состоять из нескольких шагов, атомарность гарантируется соглашением между разработчиком компилятором и производителем железа. Более того инструкция процессора тоже может быть разбита на шаги и неатомарна. Например запись 64 битного числа может быть реализована как запись старшего/младшего состояния и без поток прочитал состояние между ними

на x86 32-битная операция mov атомарна в том случае, когда операнд в памяти выровнен, и не атомарна если не выровнена

2 вообще зависит от архитектуры процессора и конкретных инструкций. Простые инструкции типа mov или xchg могут наблюдаться как физически атомарные, которые никакое прерывание не может, простите за тавтологию, прервать посередине.

В этом спинлоке

struct waiting_spinlock_ttas {
  std::atomic<bool> locked{false};
 
#define do_nothing
  void lock() { 
     for (;;) {
       if (!locked.exchange(true)) return;

       for (; locked.load();){
         for (volatile s32 i = 0; i < 24 * 100 ; i += 1) do_nothing;
       }
     }
  }
  void unlock() { locked.store(false); }
};

Количество итераций холостого цикла (в данном случае это 24 * 100) по каким критериям подбирать?

По опыту использования в разных проектах подбираем от сложности вычислений * количество тредов, также неплохо ведут себя ожидания с простыми числами, бэкофф ожидание тоже неплохо себя показало

Низкое время на одном потоке, объяснить не могу. Походу какие-то трюки ОС, когда нет претендентов на критическую секцию.
Так и есть. См. SetCriticalSectionSpinCount() ;-). Критическая секция в многоядреных системах сначала используется спинлок и только потом переключается на семафор.

Статья просто топ, большой труд автора респект!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории