2013-05-08 6 views
1

Почему java.nio.FileChannel transferTo() и transferFrom() быстрее, чем байтовые байты (потоковая передача или использование ByteBuffer) на некоторых комбинациях JVM/OS ???Почему java.nio.FileChannel transferTo() и transferFrom() быстрее ??? Использует ли он DMA?

Используют ли эти методы прямой доступ к памяти (DMA) в отличие от выдачи запросов прерывания (IRQ) для каждой передачи байтов?

+0

Оба. IRQ используется для передачи диска, который затем выполняется через DMA. Это не относится к NIO или Java: так работают операционные системы на протяжении десятилетий. Не настоящий вопрос. – EJP

ответ

3

Используют ли эти методы прямой доступ к памяти (DMA) в отличие от выдачи запросов прерывания (IRQ) для каждой передачи байта?

Спецификации соответствуют фактической реализации, и они не обязаны использовать какой-либо конкретный механизм. Это намекают в документации transferTo (курсив):

Этот метод потенциально гораздо эффективнее, чем простой цикл, который считывает данные из этого канала и записывает в целевой канал. Многие операционные системы могут передавать байты непосредственно из кэша файловой системы на целевой канал, не копируя их.

«Потенциально», «много» ... так что никаких гарантий.

Имеет смысл предположить, что , вероятно, более эффективно использовать метод, если только незначительно, потому что вы разрешаете JVM сокращать собственный код (при использовании поддерживаемых типов каналов). «Простой цикл» они описывают произведения вроде как ниже:

ByteBuffer buf = ByteBuffer.allocateDirect(BUF_SIZE); 
while (/* read more condition */) { 
    source.read(buf); 
    buf.flip(); 
    target.write(buf); 
    buf.compact(); 
} 

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

Использование transferTo/transferFrom, однако, оставляет его в JVM, чтобы решить, как передать байты. Если платформа имеет встроенную поддержку такого рода передач, она может сделать это без создания промежуточных буферов. Если такой поддержки нет, the JVM can still implement a loop such as above.

Пример: предположим, что SocketChannel предлагается считывать данные непосредственно из FileChannel через transferFrom. Недавно FileChannel был прочитан, а его содержимое находится в кеше операционной системы. Вместо того, чтобы читать и копировать байты в буфер, SocketChannel может указывать непосредственно в кэш-память ОС и начинать передачу оттуда. По крайней мере один раунд копирования устранен.

Теперь предположим, что сокет (A) фактически связан с каким-либо другим локальным процессом, например, используя какой-то канал, называемый SocketChannel B. Когда B начинает читать то, что он получил от A, он может действительно читать прямо из кэша файлов OS снова. Если тогда B просто использует transferTo для другого канала ... вы получаете идею.

0

Существует некоторое объяснение в FileChannel API

This method is potentially much more efficient than a simple loop that reads from the source channel and writes to this channel. Many operating systems can transfer bytes directly from the source channel into the filesystem cache without actually copying them. 

BTW как о переходе() и transferFrom() являются абстрактными, так что все зависит от фактической реализации

+0

Спасибо за ваш вклад. Я знаю, что мой вопрос заслуживает ответа RTFM. Меня раздражает то, что javadoc настолько расплывчата, поэтому было бы здорово, если бы кто-то с глубоким знанием о деталях реализации JVM мог предоставить больше ясности по этому вопросу. Я полагаю, что вопрос о DMA vs IRQ так же касается аппаратного обеспечения, как и для операционной системы ... – murungu

0

Он использовать DMA/Zero-копии , таким образом сохраняя переход от буфера «От» к ЦП, а затем переход от ЦП к буфере «в». Для более детального объяснения читайте this статьи IBM

+0

* Все * в дисковых передачах, упомянутых в статье, используется DMA, а не просто 'transferFrom/To()'. – EJP

0

В следующей статье, на нулевой копии

https://www.ibm.com/developerworks/linux/library/j-zerocopy/

авторы объясняют, что новые методы являются более эффективными на Linux, так как они снижают переключения контекста и уменьшить ненужное копирование буфера из ядра в приложение и обратно.

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

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