Comments 5
Во-вторых, помимо кэша есть еще 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ядерный процессор)
"Фактически, большинство современных процессоров имеют слой кэш-памяти некоторого размера"
- "некоторого размера" избыточная фраза, в русском языке она ничего не уточняет и не нужна. Да и фактически лишнее.
"Большинство современных процессоров имеют слой кэш-памяти."
"Он может даже считывать часть данных из кэша в свои внутренние регистры и затем выполнять операции над ними."
- "даже" добавляет неправильный окрас предложению. Предложение построенно так, как будто это какая-то особая функциональность а не базовая. (пример предложения с таким же окрасом — "Мы открыли все окна, двери и Даже снесли стену чтобы проветрить")
"Он может читать часть данных из кэша в регистры и выполнять над ними операции"
Хотя тут корректнее наверное будет — "Для выполнения операций над данными ядро процессора читает данные из кэша в регистры."
"Кэш может одновременно записывать данные в часть своей памяти и одновременно очищать часть своей памяти"
- по русски "Кэш может одновременно записвать данные в одну часть своей памяти и очищать другую".
И такого очень много. Даже зная предмет о котором речь читать тяжело.
Java-модель памяти (часть 2)