Является ли вызов функции эффективным барьером памяти для современных платформ?

В кодовой базе, которую я просмотрел, я нашел следующую идиому.

void notify(struct actor_t act) {
    write(act.pipe, "M", 1);
}
// thread A sending data to thread B
void send(byte *data) {
    global.data = data;
    notify(threadB);
}
// in thread B event loop
read(this.sock, &cmd, 1);
switch (cmd) {
    case 'M': use_data(global.data);break;
    ...
}

«Подождите, — сказал я автору, старшему члену моей команды, — здесь нет барьера памяти! Вы не гарантируете, что global.dataбудет сброшен из кеша в основной памяти. Если поток A и поток B будут работать на двух разных процессорах - эта схема может дать сбой".

Старший программист ухмыльнулся и медленно объяснил, как будто объясняя своему пятилетнему сыну, как завязывать шнурки: «Слушай, мальчик, мы видели здесь много ошибок, связанных с потоками, в тестировании с высокой нагрузкой и в реальных клиентах. ", он сделал паузу, чтобы почесать свою длинную бороду, "но у нас никогда не было ошибок с этой идиомой".

«Но ведь в книге написано...»

«Тихо!», он тут же шикнул на меня, «Может быть, теоретически это не гарантируется, но на практике тот факт, что вы использовали вызов функции, фактически является барьер памяти.Компилятор не будет переупорядочивать инструкцию global.data = data, поскольку он не может знать, использует ли кто-либо ее в вызове функции, а архитектура x86 гарантирует, что другие ЦП увидят это часть глобальных данных к тому времени, когда поток B читает команду из конвейера. Будьте уверены, у нас достаточно проблем реального мира, о которых нужно беспокоиться. Нам не нужно вкладывать дополнительные усилия в фиктивные теоретические проблемы.

«Будьте уверены, мой мальчик, со временем вы научитесь отделять настоящую проблему от не-проблем, связанных с тем, что мне нужно получить докторскую степень».

Он прав? Действительно ли это не проблема на практике (скажем, x86, x64 и ARM)?

Это противоречит всему, что я узнал, но у него действительно длинная борода и очень умный вид!

Дополнительные баллы, если вы покажете мне фрагмент кода, доказывающий его неправоту!

66
задан Craig McQueen 28 November 2017 в 03:26
поделиться