Почему инструкцию CompareAndSwap считают дорогой?

Почему инструкцию CompareAndSwap считают дорогой?

Я читал в книге:

"Барьеры памяти являются дорогими, почти столь же дорогими как атомарный compareAndSet () инструкция".

Спасибо!

10
задан eyalw 4 June 2010 в 08:02
поделиться

5 ответов

"CAS не сильно отличается от обычного хранилища. Часть дезинформации относительно CAS, вероятно, возникла из-за первоначальной реализации lock:cmpxchg (CAS) на процессорах Intel. Префикс lock: вызывал подачу сигнала LOCK#, получая эксклюзивный доступ к шине. Это, конечно, не помогло. Последующие реализации lock:cmpxchg используют протокол когерентности кэша - обычно MESI на основе snoop - и не подают сигнал LOCK#." - Дэвид Дайс, Biased locking in HotSpot

"Барьеры памяти дороги, примерно так же дороги, как атомарная инструкция compareAndSet()."

Это совершенно верно.
Например, на x86, правильный CAS на многопроцессорной системе имеет префикс блокировки.
Префикс блокировки приводит к полному барьеру памяти:

"...заблокированные операции сериализуют все невыполненные операции загрузки и хранения (то есть, ждут их завершения)". ... "Заблокированные операции являются атомарными по отношению ко всем другим операциям с памятью и всем видимым извне событиям. Только выборка инструкций и доступ к таблице страниц могут передавать заблокированные инструкции. Заблокированные инструкции могут использоваться для синхронизации данных, записанных одним процессором и считанных другим процессором." - Руководство разработчика программного обеспечения для архитектур Intel® 64 и IA-32, глава 8.1.2.

Барьер памяти фактически реализован как фиктивный LOCK OR или LOCK AND в .NET и JAVA JIT на x86/x64.
На x86 CAS приводит к полному барьеру памяти.

На PPC все обстоит иначе. Пара LL/SC - lwarx & stwcx - может быть использована для загрузки операнда памяти в регистр, затем либо записи его обратно, если не было другого сохранения в целевое место, либо повторения всего цикла, если оно было. Цикл LL/SC может быть прерван.
Это также не означает автоматический полный забор.
Характеристики производительности и поведение могут сильно отличаться на разных архитектурах.
Но опять же - слабая LL/SC не является CAS.

15
ответ дан 3 December 2019 в 16:51
поделиться

"дорого" здесь очень относительно. Это абсолютно несущественно по сравнению, скажем, с доступом к жесткому диску. Но скорость шины ОЗУ не поспевает за скоростью современных ЦП, и по сравнению с арифметическими операциями внутри ЦП прямой доступ к ОЗУ (т. Е. Без кеширования) обходится довольно дорого. На выборку int из ОЗУ может уйти в 50 раз больше времени, чем на добавление двух регистров.

Таким образом, поскольку барьеры памяти в основном вызывают прямой доступ к ОЗУ (возможно, для нескольких процессоров), они относительно дороги.

3
ответ дан 3 December 2019 в 16:51
поделиться

Думаю, я нашел ответ в своей книге:

Каждый getAndSet () транслируется на шину. потому что все потоки должны использовать шину для связи с памяти, эти вызовы getAndSet () задерживают все потоки (ядра), даже те, кто не ждет блокировки.

Что еще хуже, вызов getAndSet () заставляет другие процессоры отказаться от своих кэшированных копий блокировку, поэтому каждый вращающийся поток встречает кеш промахивается почти каждый раз и должен использовать автобус, чтобы получить новое, но неизменное значение.

2
ответ дан 3 December 2019 в 16:51
поделиться

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

Поток 1

while (1) x++;

Поток 2

while (1) x++;

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

Поток 1

while (1) atomicIncrement(&x);

Поток 2

while (1) atomicIncrement(&x);

Теперь вы пытаетесь получить четко определенное поведение - независимо от порядка, x должен шагать один за другим. Если два потока работают на разных процессорах, они должны либо уменьшить количество разрешенного кэширования, либо иным образом «сравнить заметки», чтобы убедиться, что происходит что-то разумное.

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

1
ответ дан 3 December 2019 в 16:51
поделиться

Это потому, что они вводят дополнительные накладные расходы, чтобы сделать операцию атомарной. Базовая платформа должна будет подавлять оптимизацию (например, кеширование) и приостанавливать выполнение потоков для облегчения барьера, а это требует больших дополнительных усилий. Пока эта дополнительная активность выполняется, потоки не могут выполняться, поэтому для всей программы возникает временная задержка.

3
ответ дан 3 December 2019 в 16:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: