2013-08-13 2 views
11

ФОНИспользование sun.misc.Unsafe, что является самым быстрым способом сканирования байтов из прямого байтового буфера?

Предположим, у меня есть прямой ByteBuffer:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 

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

Передача времени сокета в напрямую ByteBuffer является фантастическим, потому что все это происходит в памяти собственной ОС; Я не прошел через «гематоэнцефалический барьер» JVM еще ...

ВОПРОС

Предполагая, что моя работа состоит в том, чтобы просканировать все прочитанные байты снова из прямого буфера байт, что самый быстрый способ для этого?

Первоначально я спросил: «... используя sun.misc.Unsafe», но, возможно, это неправильное предположение.

ВОЗМОЖНЫЕ ПОДХОДЫ

В настоящее время я вижу три подхода и один я самым любопытным является # 3:

  1. (DEFAULT) Использование ByteBuffer-х bulk-get тянуть байты непосредственно из родного пространства ОС в внутренний байт [1024].
  2. (UNSAFE) Используйте операторы Unsafe's getByte, чтобы вытащить значения непосредственно из ByteBuffer, пропустив все проверки границ стандартных операций ByteBuffer. Ответ Питера Лоури here, по-видимому, предполагал, что эти исходные собственные методы в Unsafe даже могут быть оптимизированы компилятором JIT («intrinsics») на отдельные машинные команды, что приведет к еще более фантастическому времени доступа. (=== UPDATE === интересно, похоже, что базовый класс DirectByteBuffer делает именно это с get/put ops для тех, кто интересуется.)
  3. (BANANAS) В некотором роде способов преступности против человечества, используя Unsafe, может ли я copy the memory region прямого ByteBuffer на тот же адрес памяти, что мой байт [1024] существует внутри виртуальной машины и только начинает получать доступ к массиву с использованием стандартных индексов int? (Это делает предположение о том, что «CopyMemory» операция может потенциально сделать что-то сказочно оптимизированное на уровне операционной системы.

Это происходит со мной, что в предположении CopyMemory операцию делает именно то, что она рекламирует, даже в более -оптимальное пространство ОС, что описанный выше подход № 2, вероятно, по-прежнему наиболее оптимизирован, так как я не создаю дубликаты буфера перед началом его обработки.

Это отличается от вопроса «can I use Unsafe to iterate over a byte[] faster?», поскольку я даже не планирование по извлечению байтов в байт [] внутренне, если нет необходимости.

Спасибо за время; просто любопытно, если кто-нибудь (Питер?) получил орехи с Unsafe, чтобы сделать что-то вроде этого.

ответ

1

ByteBuffer методы чрезвычайно быстры, потому что эти методы являются внутренними, VM отображает их в инструкции очень низкого уровня. Сравните эти два подхода:

byte[] bytes = new byte[N]; 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bytes.length; i++) 
      sum += bytes[i]; 

    ByteBuffer bb = ByteBuffer.allocateDirect(N); 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bb.remaining(); i++) 
      sum += bb.get(i); 

На моей машине разница 0,67ns против 0,81ns (за цикл).

Я немного удивлен, что ByteBuffer не так быстро, как byte []. Но я думаю, что вы обязательно НЕ копируете его в байт [], затем получите доступ.

+0

Не знал о «внутреннем» свойстве методов ByteBuffer; вы имеете в виду «родные» методы в классе DirectBuffer? В этом случае это будет делать то, что № 2 будет делать в моем сообщении выше, так что это отличная новость. –

+0

@RiyadKalla intrinsic! = Native. Внутренние методы «жестко закодированы» в JVM. – assylias

+0

@assylias Я понимаю; Я был (неправильно) со ссылкой на то, что, как я понял, был «родным» методом в классе DirectByteBuffer impl (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java /nio/DirectByteBuffer.java), но теперь, когда я смотрю на него, я вижу, что нет «родных» методов, он просто использует Unsafe для выполнения этих операций. Я ошибаюсь, благодарю вас за улов. –

 Смежные вопросы

  • Нет связанных вопросов^_^