Барьеры памяти и TLB

Барьеры памяти гарантируют, что кэш данных будет согласованным. Однако гарантирует ли это, что TLB будет согласованным?

Я наблюдаю проблему, когда JVM (java 7 update 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's memcpy(), указывающие на то, что я пытаюсь получить незаконный доступ к памяти. С Thread.yield() у меня не было проблем, но это не кажется надежным решением.

Кто-нибудь сталкивался с этой проблемой? Есть ли какие-либо гарантии относительно TLB и барьеров памяти?


EDIT: ОС - Centos 5.7, я наблюдал такое поведение на машинах i7 и Dual Xeon.

Почему я это делаю? Потому что среднее время записи сообщения составляет 35-100 нс в зависимости от длины, а использование простого write() не так быстро. Если я создаю карту памяти и очищаю ее в текущем потоке, это занимает 50-130 микросекунд, а если использовать фоновый поток для этого, то основному потоку потребуется около 3-5 микросекунд, чтобы поменять буферы местами. Почему мне вообще нужно менять буферы местами? Потому что я записываю много ГБ данных, а размер ByteBuffer не может быть 2+ ГБ.

27
задан Rob Kielty 3 May 2012 в 05:11
поделиться