LINUX.ORG.RU

Проблема: как инвалидировать процессорный кэш на SMP?


0

0

Вообще-то, ccNUMA.

Пусть *ptr указывает на разделяемую память.

Я туда написал кое-что из процессора 0. Как бы мне посвистеть остальным процессорам, чтобы они соотв. кэш обновили?

Ядро 2.4.21

★★★★★

Вопрос снимается (оно автоматом делается, а мои проблемы заключались в реристрах, volatile помогло)

Die-Hard ★★★★★
() автор топика

никак. вы можете сделать cache flush на процессоре 0,
но ничто не может заставить другие процессоры сделать
invalidate cache.

в kernel mode вы можете сделать smp_call_function(),
передав указатель на функцию, которая это сделает.
очень дорого.

обычно делается так: на процессоре 0 wmb() после записи,
остальные должны делать rmb() перед чтением. это _не_
гарантирует, что вы прочитете уже новое значение, но зато
гарантирует, что предыдущие результаты операций чтения не
"новее". как правило, этого достаточно.

idle ★★★★★
()
Ответ на: комментарий от Die-Hard

> оно автоматом делается

оно _не_ делается автоматом. даже на i386 есть
окно, в течение которого вы можете получить
stale data.

idle ★★★★★
()
Ответ на: комментарий от idle

> > оно автоматом делается
>
> оно _не_ делается автоматом

то есть, пардон, делается конечно на cache coherent
архитектурах, но окно таки есть

idle ★★★★★
()
Ответ на: комментарий от idle

idle (29.10.2004 13:24:02):

> ...делается конечно на cache coherent архитектурах,

У меня как раз cc. В SGI обещали, что любая запись любого процессора аппаратно инвалидирует соответствующие линейки на всех остальных.

Но вот окно...

> ...обычно делается так: на процессоре 0 wmb() после записи, ...

А из userspace'а?

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

> Но вот окно...

и это не единственная проблема.
пусть a = b = 0. cpu0 делает a = 1, b = 2;

действительно, к другим процессорам пойдет ipi про
invalidate, но когда оно придет, и в каком порядке...

поэтому другой процессор может, скажем, прочитать
эти переменные как a == 0, b == 2. или a = 1, b = 2.

> > ...обычно делается так: на процессоре 0 wmb() после записи, ...
>
> А из userspace'а?

я не скажу за всю Одессу, но кажется, эти операции
не требуют привилегий. вообще-то, я думаю в libpthreads
должны быть какие-то хелперы, но я не знаю.

idle ★★★★★
()
Ответ на: комментарий от idle

Люди а можно поподробнее
у меня таже проблема и что-то в гугле про wmb()
я ничего не нашел счас семафорами разруливаю но это
жутко тормознуто и ограничений ряд накладывает

anonymous
()
Ответ на: комментарий от anonymous

попробуйте поискать memory barrier, может найдете.
не знаю, где про это можно прочитать.

idle ★★★★★
()
Ответ на: комментарий от idle

>оно _не_ делается автоматом. даже на i386 есть >окно, в течение которого вы можете получить >stale data.

обновление натурально выровненных данных на Intel SMP всегда атомарно.

обновление ненатурально выровненных данных на Intel SMP атомарно при условии блокировки шины на время обновления (префикс LOCK).

когерентность кэшей агентов на Intel SMP всегда имеет место быть благодаря snoop cycles, окон при условии атомарности обновления быть не может.

Murr ★★
()
Ответ на: комментарий от Murr

Murr:
> обновление натурально выровненных данных на Intel SMP
> всегда атомарно.

дело не в атомарности. я действительно неточно выразился
в первом посте, т.к. отвечал в контексте обсуждения
синхронизации в соседней ветке.

я утверждаю, что не существует способа сделать так, чтобы
после "этого момента" другие cpu _гарантированно_ прочитали
новое значения.


idle ★★★★★
()
Ответ на: комментарий от idle

> я утверждаю, что не существует способа сделать так, чтобы
> после "этого момента" другие cpu _гарантированно_ прочитали
> новое значения.

разумеется, я не имею в виду специальные примитивы, типа xhcg().
но такие операции, вообще говоря, с кэшем и не работают.

idle ★★★★★
()
Ответ на: комментарий от idle

>разумеется, я не имею в виду специальные примитивы, типа xhcg(). >но такие операции, вообще говоря, с кэшем и не работают.

По-моему, обычная загрузка (mov) по выровненному адресу вызывает на snoop шине выставление адреса (обращение по невыровненному адресу - несколько запросов) и в тот же самый момент (в тот же цикл слежения, который на Intel тактируется одинаково с процессором) вызывает invalidate aliases данных по данному адресу на всех процессорах.

По идее, процессор может переупорядочивать выполнение кода и именно из-за него нужны memory barriers(чтобы обеспечить определенный порядок внешней видимости изменения данных и порядок доступа). Но, при етом ,с точностью до порядка выполнения операций, изменения всех aliases производятся синхронно (на Intel).

Вообще, интересная тема... давненько я подобными вещами занимался. :)

Murr ★★
()
Ответ на: комментарий от Murr

> По-моему, обычная загрузка (mov) по выровненному адресу вызывает на snoop
> шине выставление адреса (обращение по невыровненному адресу - несколько запросов)
> и в тот же самый момент (в тот же цикл слежения, который на Intel тактируется
> одинаково с процессором) вызывает invalidate aliases данных по данному
> адресу на всех процессорах.

очень может быть. но. вы не знаете наверное, когда этот mov начнет
выполняться, даже на pentium'ах есть write buffers. причем здесь
я не имею в виду переупорядочивание кода, считаем, что mov уже
выполнена. то есть у нас уже выполняются следующие инструкции, а
mov пока еще только _считывает_ cache line, в случае cache miss.

> По идее, процессор может переупорядочивать выполнение кода и именно из-за
> него нужны memory barriers(чтобы обеспечить определенный порядок внешней
> видимости изменения данных и порядок доступа).

нет, совершенно точно не только по этой причине. порядок передачи
данных может изменить и шина (только не ловите меня на слове, я не
владею терминологией :). кроме того, даже с барьерами другая сторона
должна делать rmb(), иначе, опять таки, никаких гарантий.

собственно, как и с atomic операциями. если процессор делает
atomic_set(), то это не гарантирует, что другой cpu после этого
момента прочитает новое значение. только, если он будет это
делать с помощью atomic_read(), которая, вообще говоря, не
просто load.

хотя на всех i386 у нас, кажется strong ordering. хотя...
include/asm/system.h:
#ifdef CONFIG_X86_OOSTORE
#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)

> Вообще, интересная тема... давненько я подобными вещами занимался. :)

интересная, и лично я в ней разбираюсь меньше, чем хотелось бы.

idle ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.