Есть ли что-нибудь, что мешает процессору долго ждать перед выполнением запланированных операций с наборами?

Допустим, у меня есть два потока, которые совместно используют глобальную переменную x. Задача Thread A — установить значение x, а задача Thread B — прочитать x. Теперь каждый поток (или, я полагаю, каждое ядро) будет иметь кэшированную копию x.

Предположим, что Thread A установил значение x в 12345. Теперь кеш Thread A может оставаться неизменным, потому что ЦП может запланировать выполнение операции set позже, и поэтому протокол когерентности кеша не будет действовать, и поэтому, когда Thread B считывает значение x, он будет считывать старое значение.

Мой вопрос: есть ли что-нибудь, что мешает процессору долго ждать (например: 10 минут) перед выполнением запланированных операций набора?

Примечание. Я знаю, что могу использовать барьер памяти, чтобы заставить ЦП немедленно выполнять запланированные операции набора, но мне любопытно узнать, что может произойти, если я не использую память барьер.


person Christopher    schedule 15.03.2017    source источник
comment
используйте volatile для этой переменной (x), чтобы она не кэшировала значение ни в потоке A, ни в B   -  person ntshetty    schedule 15.03.2017
comment
Нет. Но многие события, включая отправку исключений, все равно очищают буфер хранилища.   -  person Margaret Bloom    schedule 15.03.2017
comment
Ошибки гонки потоков вызываются задержками, измеряемыми в наносекундах. То, что он такой короткий, делает такие ошибки такими сложными для отладки.   -  person Hans Passant    schedule 15.03.2017
comment
По касательной: документ cs.tau.ac.il/ ~mad/publications/asplos2014-ffwsq.pdf предлагает использовать ограничение длины очереди хранилища, чтобы избежать использования ограждения. Но обратите внимание, что авторы рассуждают о длине буфера, а не о времени.   -  person Arch D. Robison    schedule 17.03.2017


Ответы (1)


Ни одна документация по ЦП, которую я читал за последние 15 лет, не говорит о времени, необходимом для синхронизации памяти, в более конкретных терминах, чем «X виден раньше Y». Причина этого в том, что протоколы памяти настолько сложны, что почти невозможно установить верхнюю границу того, сколько может произойти, прежде чем ваша запись станет видимой (DMA, исправление ошибок, поиск TLB, SMM и т. д.).

Вы можете построить теоретический сценарий, в котором ваша запись никогда не станет видимой, на самом деле, если вы хотите сделать это, просто найдите документы об ошибках для процессоров, и у них будет множество примеров того, как это может произойти. А на практике? Нет, ты никогда не будешь ждать 10 минут. Ядро, на котором вы работаете, будет получать прерывания, которые будут выполнять операции чтения и записи памяти, которые будут сбрасывать буферы хранилища и удалять ваши строки кэша.

При этом вы все равно должны использовать синхронизацию памяти, но по другим причинам. Для обеспечения выполнения заказа. Если значение x является единственным битом информации, который вы хотите отправить другому потоку, он в конечном итоге станет доступным для чтения, и вы можете отказаться от синхронизации. Но это почти никогда не бывает. Обычно значение x говорит о том, что значение y содержит что-то интересное, и вам нужна надлежащая синхронизация, чтобы знать, что y имеет правильное содержимое, когда x становится видимым для другого потока.

person Art    schedule 15.03.2017