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

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

На сколько я знаю, кэш даже в обычных комп-ах (не суперкомпьютеры, там я хз) когерентен между CPU в многопроцессорных системах, a в кэше одного многоядерного камня и подавно. Некоторые технологии когерентности: Intel MESIF, AMD MOESI.
Тут важно понимать две вещи. Первое — Java Memory Model является попыткой абстрактно описать наиболее вероятные реализации аппаратных платформ. Она обеспечивает приемлемую производительность на существующих архитектурах, и (мы надеемся) даже на тех, которые еще не оформлены в реальных процессорах и машинах. Поэтому JMM не может делать предположение, что составные части процессора или разные процессоры имеют синхронизацию кэша (или она достаточно дешево работает).

Во-вторых, помимо кэша есть еще out-of-order execution. И вот с этим вы простой синхронизацией кэша ничего не сделаете. Ядро обязано переупорядочивать операции внутри своего конвейера так, чтобы с его (!) точки зрения результат был эквивалентен потоку изначальных операций. Но эта эквивалентность может (и будет) нарушаться с точки зрения соседних ядер. Например, выполняя последовательность операций A=A+1;B=5 ядро вынуждено упорядочить операции чтения и записи A (ну потому что иначе нельзя прибавить к нему единицу). Что касается присвоения B — оно (с точки зрения этого ядра) является чистым побочным эффектом, и его можно выполнить до присвоения A (например, пока АЛУ прибавляет единицу). А можно после. А другое ядро может выполнять свою, неизвестную первому ядру программу — где критично именно чтобы B записалось после A. Выявить такие зависимости в общем виде — невозможно. Поэтому появляются механизмы типа memfence, которые заставляют процессор гарантировать что до этой операции чтения все операции записи исполнены. Ценой просадки производительности, естественно. Java Memory Model своими happens-before задает правила, где мы жертвуем определенностью ради скорости, а где — наоборот.

А, да — еще третий фактор забыл — JIT. Например, имея последовательность операций A=A+B; A=A+C;A=A+D — компилятор и JIT в рантайме имеют по-умолчанию полное право один раз считать A в регистр, и сбросить его в память (не важно, в кэш или RAM) только после последнего сложения. Запрещать свосем это нельзя — ибо производительность. Вот и тут JMM задает пределы, до которых компилятор и JIT имеют право интерпретировать наши намерения. И в целом, сравнивая существующее положение с миром C++ — мы живем даже очень неплохо!

Ох. Перевод как минимум стоит перечитать, адаптировать на русский. Многие предложения стоит перестроить, вырезать части, которые в русском остались незначащими хвостами. Примеры ниже.


Так же по ощущениям периодически перепутаны термены Ядро и Процессор.


Вместо "Основной памяти" наверное следовало везде использовать RAM или ОЗУ тем более что термин раскрывается в самой статье.


"Каждый ЦП содержит набор регистров, которые, по существу, находятся в памяти ЦП" — вот тут вероятнее всего имеется в виду "Каждое ядро процессора содержит набор регистров которые находятся непосредственно на нем." да и фраза по существу тут как-то неуместна.


"Процессор может выполнять операции с этими регистрами намного быстрее, чем с переменными в основной памяти."


  • тут как то коряво — регистры противопоставляются переменным. Тогда как в регистрах вообще тоже переменные. Лучше было бы — "Операции с данными в регистрах выполняются наиболее быстро."
    или "Операции с данными в регистрах выполняются значительно быстрее, чем с данными в ОЗУ".

"Это означает, что если ваше Java-приложение является многопоточным, то внутри вашей программы может быть запущен одновременно один поток на один процессор."


  • вот тут тоже наверное один поток на одно ядро, а не на один процессор. Утверждение конечно тоже верное, но выглядит как минимум странно — 4х ядерный процессор способен выполнять один поток на один процессор, но может и все четыре) (а с hyper threading так и все 8, но логически это будет 8ядерный процессор)

"Фактически, большинство современных процессоров имеют слой кэш-памяти некоторого размера"


  • "некоторого размера" избыточная фраза, в русском языке она ничего не уточняет и не нужна. Да и фактически лишнее.
    "Большинство современных процессоров имеют слой кэш-памяти."

"Он может даже считывать часть данных из кэша в свои внутренние регистры и затем выполнять операции над ними."


  • "даже" добавляет неправильный окрас предложению. Предложение построенно так, как будто это какая-то особая функциональность а не базовая. (пример предложения с таким же окрасом — "Мы открыли все окна, двери и Даже снесли стену чтобы проветрить")
    "Он может читать часть данных из кэша в регистры и выполнять над ними операции"
    Хотя тут корректнее наверное будет — "Для выполнения операций над данными ядро процессора читает данные из кэша в регистры."

"Кэш может одновременно записывать данные в часть своей памяти и одновременно очищать часть своей памяти"


  • по русски "Кэш может одновременно записвать данные в одну часть своей памяти и очищать другую".

И такого очень много. Даже зная предмет о котором речь читать тяжело.

У меня, действительно, были «завтыки» по всем этим пунктам и была версия перевода практически в точности, как вы предлагаете. Но потом я решил всё же оставить ближе к оригиналу, поскольку сомневался в своей компетентности что-либо менять. Теперь, пожалуй, ещё раз всё пересмотрю и больше адаптирую. Спасибо за такой развёрнутый комментарий!
Насчёт процессора всё же сделал лишь примечание, а остальное не менял. Автор разделил понятия процессора и ядра, но всё же использовал далее именно «процессор». Видимо он посчитал, что так надо, думаю не в моих полномочиях это менять :) Тоже самое и с «основной памятью». Суть он названий не меняется и она вполне ясна.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории