Я хотел бы начать доступ к основной памяти, но пока я получаю новое значение в какой-то момент, я не слишком суетлив относительно того, когда именно новое значение прибывает. А пока я хотел бы продолжить использовать значение, которое в данный момент находится в регистре, а не останавливаться до тех пор, пока загрузка памяти не завершится.
Вот пример мотивирующей игрушки на C. У меня есть рабочий цикл, который постоянно выполняет некоторую работу и накапливает результаты в некотором хранилище. Время от времени я хотел бы поменять местами, где накапливаются значения (аналогично ротации журналов на сервере Linux). Пока каждое вычисленное значение накапливается в одном месте хранения, я счастлив.
Как написано, процессор будет зависать, пока происходит выборка памяти, потому что я не говорил, что хочу использовать ранее существующее значение «неправильный / устаревший» в регистре, пока выборка памяти не завершится.
Как я могу сделать это понятным компилятору / процессору? Это нормально, если для этого требуется непосредственно писать сборку. Мне интересны ответы, которые работают на любой / всех архитектурах.
// does unspecified work and returns an int.
inline int do_work();
// where our main thread accumulates its work
int * accumulator;
// assume that some other thread is concurrently updating this.
// Every so often, we want to switch our accumulator to be a
// newer value taken from here, but we're not fussy about exactly
// when that switch happens.
int * volatile * current_accumulator;
void work_loop() {
int * accumulator = *current_accumulator;
// Here, I want to block once until `*current_accumulator`
// is loaded into a register.
while (1) {
for (int i = 0; i < 100; ++i) {
// This has a dependency on the memory load, and so
// it will stall until the new value is loaded into
// the register. However I don't want that. I want the
// register to update eventually, but I want to always
// be using the value that happens to currently be there.
*accumulator += do_work();
}
accumulator = *current_accumulator;
}
}