Барьеры памяти гарантируют, что кэш данных будет согласованным. Однако гарантирует ли это, что TLB будет согласованным?
Я вижу проблему, когда JVM (Java 1 обновление 1) иногда дает сбой с ошибками памяти (SIGBUS, SIGSEG) при передаче MappedByteBuffer между потоками.
, например
final AtomicReference<MappedByteBuffer> mbbQueue = new AtomicReference<>();
// in a background thread.
MappedByteBuffer map = raf.map(MapMode.READ_WRITE, offset, allocationSize);
Thread.yield();
while (!inQueue.compareAndSet(null, map));
// the main thread. (more than 10x faster than using map() in the same thread)
MappedByteBuffer mbb = inQueue.getAndSet(null);
Без Thread.yield () я иногда получаю сбои в force (), put () и C memcpy (), все это указывает на то, что я пытаюсь получить доступ к памяти незаконно. С Thread.yield () у меня не было проблемы, но это не похоже на надежное решение.
Кто-нибудь сталкивался с этой проблемой? Есть ли какие-либо гарантии относительно TLB и барьеров памяти?
РЕДАКТИРОВАТЬ: ОС Centos 5.7, я видел поведение на i7 и машинах Dual Xeon.
Почему я это делаю? Поскольку среднее время написания сообщения составляет 35-100 нс, в зависимости от длины и использование простой записи () не так быстро. Если я отображаю карту памяти и очищаю ее в текущем потоке, это занимает 50-130 микросекунд, а использование фонового потока занимает около 3-5 микросекунд, когда основной поток меняет местами буферы. Зачем мне вообще менять буферы? Поскольку я пишу много ГБ данных, а размер ByteBuffer не может превышать 2 ГБ.