Самый быстрый встроенный -сборочный спинлок

Я пишу многопоточное приложение на С++, где производительность имеет решающее значение. Мне нужно использовать много блокировок при копировании небольших структур между потоками, для этого я решил использовать спин-блокировки.

Я провел небольшое исследование и тестирование скорости и обнаружил, что большинство реализаций примерно одинаково быстры :

  • . CRITICAL _SECTION от Microsoft с параметром SpinCount, установленным на 1000, оценивается примерно в 140 единиц времени
  • . Реализация этого алгоритма с Microsoft InterlockedCompareExchange дает около 95 единиц времени
  • Я также пытался использовать некоторый встроенный ассемблер с __asm {}, используя что-то вроде этого кода , и он оценивает около 70 единиц времени, , но я не уверен, что был создан надлежащий барьер памяти.

Изменить :Время, указанное здесь, — это время, необходимое двум потокам для блокировки и разблокировки спин-блокировки 1 000 000 раз.

Я знаю, что это не большая разница, но поскольку спин-блокировка — это активно используемый объект, можно подумать, что программисты договорились о самом быстром способе создания спин-блокировки. Однако поиск в Google приводит к множеству различных подходов. Я думаю, что этот вышеупомянутый метод был бы самым быстрым, если бы он был реализован с использованием встроенного ассемблера и с использованием инструкции CMPXCHG8Bвместо сравнения 32-битных регистров. Кроме того, необходимо учитывать барьеры памяти, это можно сделать с помощью LOCK CMPXHG8B (Я думаю?), что гарантирует «исключительные права» на общую память между ядрами. Наконец [некоторые предполагают], что для ожидание занятости должно сопровождаться NOP :REP , что позволит многопоточным процессорам Hyper -переключаться на другой поток, но я не уверен, правда это или нет. нет?

Из моего теста производительности -различных спин-блокировок видно, что особой разницы нет, но чисто в академических целях я хотел бы знать, какой из них самый быстрый. Однако, поскольку у меня очень ограниченный опыт работы с языком ассемблера -и с барьерами памяти, я был бы счастлив, если бы кто-нибудь мог написать код ассемблера для последнего примера, который я предоставил с LOCK CMPXCHG8B и соответствующими барьерами памяти в следующий шаблон:

__asm
{
     spin_lock:
         ;locking code.
     spin_unlock:
         ;unlocking code.
}

24
задан Community 23 May 2017 в 12:10
поделиться