обзор
Аппаратная память транзакций может позволить нескольким потокам одновременно осуществлять спекулятивный доступ к одной и той же структуре данных и позволить протоколу когерентности кэша определять наличие конфликта. HTM стремится обеспечить вам масштабируемость точной зернистой блокировки, простоту конечно же зернистой блокировки и производительность, практически не зависящую от блокировки. Если ваша программа или библиотека была поддержана JVM, она была написана с блокировкой курса, это может означать, что ваше приложение может масштабироваться до гораздо большего числа ядер с небольшими изменениями.
Хотя добавить поддержку этого в C и C ++ нетривиально, добавление поддержки к собственному коду, сгенерированному JVM, может быть выполнено без изменения байтового кода.
Короче говоря, это может позволить многим потокам спекулятивно выполнять синхронизированные блоки для одновременной блокировки, даже одновременных записей, и процессор решает, была ли это проблемой, и повторяет блок, пока это не так.
Что такое аппаратная память транзакций и сколько она будет стоить?
Аппаратная транзакционная память существует уже некоторое время, но до недавнего времени она не была основным потоком. Благодаря внедрению Intel поддержки в некоторые из процессоров 4-го поколения i3 / i5 / i7 (Haswell) и процессоров семейства E3-1200 v3 (до 4-ядерных, с одним сокетом ATM) широко доступны для новых машин на базе Intel. Это может быть позже в этом году или в следующем году, прежде чем мы увидим большее количество ядер, что означает, что HTM будет иметь реальное значение. AFAIK, AMD планируют добавить эту функцию в ближайшее время.
Кстати, в системах Vega Azul эта технология используется уже почти десять лет, и я ожидаю, что Azul лучше всего сможет внедрить ее в JVM.
Оборудование, которое вы купите и, возможно, уже сделаете, сделает это. Многие новые модели ноутбуков имеют процессоры Haswell, поскольку они значительно улучшили энергопотребление.
Как это может работать?
Синхронизированные блоки часто используются в Java на индивидуальной основе. Чтобы упростить код, эти блокировки часто гораздо более грубые, чем оптимальные, например, Hashtable блокирует весь объект / карту для любой операции по сравнению с ConcurrentHashMap, который имеет точную блокировку зерна. Писать точную зернистую блокировку гораздо сложнее, и поэтому она более подвержена ошибкам. Цель аппаратной памяти транзакций состоит в том, чтобы поддерживать детализированную блокировку курса, но получить преимущество точной блокировки. Это особенно полезно для кода, где повторная оптимизация кода нецелесообразна.
пример
1
2
3
4
5
6
7
8
|
private final Map map = new HashMap<>(); public synchronized PooledObject acquireObject(String key) { PooledObjectobject = map.get(key); if (object == null ) map.put(key, object = new PooledObject()); return map; } |
Вы можете ожидать общего случая
- только читает карту
- обновляет карту, но в разных местах например разные ключи.
- редко пытается обновить один и тот же ключ в двух потоках одновременно.
Что бы вы хотели
- параллельное выполнение между потоками.
- очень маленький по сравнению с кодом без блокировки.
- процессор или JVM, чтобы выполнить всю работу по оптимизации этого, то есть вам не нужно менять код.
Без HTM синхронизированный блок должен получить блокировку и обеспечить сериализованный доступ, даже если в большинстве случаев это операция чтения.
С HTM байт-код может быть превращен в псевдокод, как это
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public PooledObject acquireObject(String key) { int code; do { xbegin(); PooledObjectobject = map.get(key); if (object == null ) map.put(key, object = new PooledObject()); return map; } while ((code = xend()) == RETRYABLE); if (code != DONE) { // take corrective action such as // obtain a normal lock and repeat } } |
Инструкция XEND обозначает конец, где проверяется умозрительный набор для чтения и записи в кеше, чтобы увидеть, был ли какой-либо из них доступ к какой-либо строке кеша, измененной другим ЦП / потоком. Если нет, внесенные изменения фиксируются. В противном случае любые изменения сбрасываются, и цикл можно повторить.
Примечание. Откат транзакции означает отмену изменений и может даже привести к откату создания объекта, если он не имеет значительных побочных эффектов. Если он имеет побочные эффекты, существует инструкция XABORT, которая может инициировать прерывание транзакции, и потребуется выполнить код возврата.
Compare And Swap ограничен 64-битными, каков предел этих транзакций?
Ограничение — это количество строк, которые вы можете сохранить в кеше L1. Это до 32 КБ. Если у вас есть гиперпоточность, это может быть половина, т.е. 16 КБ. Кроме того, кэш-память L1 является 8-способной ассоциативной, поэтому в худшем случае 9 строк кеша, которые хешируют в один и тот же сегмент, могут привести к сбою транзакции. (меньше с гиперпоточностью) Тем не менее, он намного выше и гораздо более гибок, чем 64-битный CAS или 128-битный CAS.
Написание этой структуры блокировки транзакций с отступлением добавляет шаблон и дублирующий код на языке, подобном C.
Вывод
Прелесть этого шаблона в том, что его можно применять к коду Java, который уже скомпилирован и доступен как библиотеки с открытым исходным кодом. В отличие от кода C, который потребует значительных переделок для использования этой функциональности, Java-программы могут использовать HTM без повторной компиляции. То, что нам нужно, это изменение в JVM.
Примечания (некоторые исправления / пояснения к тому, что я сказал ранее)
Для меня; «Крутая» технология — это та, которая, как я считаю, вызывает широкий интерес, даже если не доказана ее широкая полезность. Я считаю, что реализация этого в основной JVM поставит под вопрос то, что даже опытные разработчики «знают» о многопоточном программировании.
Хотя Intel TSX доступен в некоторых процессорах Haswell, он доступен не во всех процессорах Haswell. Вы должны проверить с Haswell на ARK и посмотреть, что Intel TSX-NI — Да .
Было отмечено, что это может не иметь большого значения для хорошо настроенного кода. Дизайнер Intel для TSX Рави Раджвар (Qav SF Rajwar) представил на QCon SF 2012 тему « Под капотом» с микроархитектурой Intel следующего поколения под кодовым названием Haswell на трассе « Механическая симпатия» . Если вы посмотрите на страницу 29, это говорит мне о том, что мелкозернистый код в любом случае будет хорошо масштабироваться по ядрам и не получит столько же. TSX может помочь, конечно же, блокировка.
Для более технических деталей я предлагаю вам прочитать пост Джила Тене о механической группе симпатий . У него больше личного опыта настройки JVM для поддержки HTM, чем у любого, с кем я встречался.
использованная литература
- Спекулятивная блокировка: преодоление масштабного барьера (JAOO 2005) от Азула Гил Тене.
- Ранний опыт внедрения коммерческой транзакционной памяти аппаратного обеспечения (октябрь 2009 г.) Дэвида Дайса, Йосси Лева, Марка Моира, Даниэля Нуссбаума, Марека Ольшевского из Sun Microsystems.
- Расширения транзакционной синхронизации в Википедии
- Тесты: Haswell TSX и пропускная способность транзакций памяти (HLE и RTM) от SiSoftware
- Удовольствие от Intel® Transactional Synchronization Расширения от Intel
- Поддержка транзакционной памяти: speculative_spin_mutex от Intel
- Понимание расширений транзакционной синхронизации Intel Haswell от Johan De Gelas.