Как заставить Java использовать мой многоядерный процессор с GZIPInputStream?

Я использую GZIPInputStream в своей программе, и я знаю, что производительность помогла бы, если бы я мог заставить Java запускать мою программу параллельно.

В общем, есть ли опция командной строки для стандартной виртуальной машины для работы на многих ядрах? Он работает только на одном как есть.

Спасибо!

Редактировать

Я запускаю обычную версию Java SE 6 update 17 на Windows XP.

Поможет ли GZIPInputStream в отдельном потоке явно помочь? Нет! Не помещайте GZIPInputStream в отдельный поток! НЕ многопоточный ввод / вывод!

Редактировать 2

Я полагаю, что узким местом является ввод / вывод, поскольку я читаю и записываю на один и тот же диск ...

В общем, есть ли способ сделать GZIPInputStream быстрее? Или замена GZIPInputStream, который работает параллельно?

Редактировать 3 Фрагмент кода, который я использовал:

GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(INPUT_FILENAME));
DataInputStream in = new DataInputStream(new BufferedInputStream(gzip));
8
задан FrustratedWithFormsDesigner 2 November 2018 в 15:07
поделиться

7 ответов

[

] AFAIK действие чтения из этого потока однопоточное, поэтому несколько процессоров не помогут вам, если вы читаете один файл. [

] [

]Однако, вы можете иметь несколько потоков, каждый из которых распаковывает отдельный файл.[

] [

]При этом распаковывание в наши дни не особенно интенсивно вычисляется, скорее всего, вы будете заблокированы стоимостью ввода-вывода (например, если вы читаете два очень больших файла в двух разных областях HD).[

] [

]В более общем плане (предполагая, что это вопрос о ком-то новичке в Java), Java не делает вещей параллельно за вас. Вы должны использовать потоки, чтобы сказать ей, какие единицы работы вы хотите сделать и как синхронизировать между ними. Java (с помощью ОС), как правило, берет столько ядер, сколько доступно, а также подменяет потоки на одном ядре, если их больше, чем ядер (что обычно и происходит). [

]
16
ответ дан 5 December 2019 в 06:23
поделиться

Оберните ваши GZIP-потоки в буферизованные потоки, это должно дать вам значительный прирост производительности.

OutputStream out = new BufferedOutputStream(
    new GZIPOutputStream(
        new FileOutputStream(myFile)
    )
)

А также для входного потока. Использование буферизированных входных/выходных потоков уменьшает количество чтений с диска

.
2
ответ дан 5 December 2019 в 06:23
поделиться

Я не вижу ответа, адресованного другим процессорам вашей программы.

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

Если вы извлекаете что-то, что приходит в разумных размерах, то ваша обработка этих блоков должна происходить в отдельном потоке от распаковки.

Вы можете вручную запустить Thread на каждой большой Строке или другом блоке данных; но начиная с Java 1. 6 или около того, вам лучше использовать один из новых причудливых классов в java.util.concurrent, например ThreadPoolExecutor.


Update

Из вопроса и других комментариев мне непонятно, действительно ли вы ARE просто извлекаете файлы с помощью Java. Если вы действительно, действительно думаете, что вам стоит попытаться конкурировать с gunzip, то вы, вероятно, можете получить некоторую производительность, используя большие буферы, т.е. работать с буфером, скажем, 10 Мб (двоичным, а не десятичным! - 1048576), заполните его одним глотком и запишите на диск аналогичным образом. Это даст вашей операционной системе шанс выполнить среднемасштабное планирование дискового пространства, и вам также понадобится меньше вызовов на системном уровне.

.
2
ответ дан 5 December 2019 в 06:23
поделиться

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

.
0
ответ дан 5 December 2019 в 06:23
поделиться

компрессия и декомпрессия с использованием gzip - это сериализованный процесс. чтобы использовать несколько потоков, вам пришлось бы сделать пользовательскую программу, чтобы разбить входной файл на множество потоков, а затем пользовательскую программу, чтобы распаковать и соединить их обратно. в любом случае, IO будет бутылочным горлышком WAY перед использованием процессора.

.
0
ответ дан 5 December 2019 в 06:23
поделиться

Запустите несколько ВМ. Каждая ВМ - это процесс, и вы должны быть в состоянии запустить как минимум три процесса на ядро без какого-либо снижения производительности. Конечно, ваше приложение должно быть в состоянии использовать многопроцессорность для извлечения пользы. Волшебной пули нет, поэтому вы видите статьи в прессе, стонущие о том, что мы еще не знаем, как использовать многоядерные машины.

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

.
0
ответ дан 5 December 2019 в 06:23
поделиться

, что пахнет мне довольно плохо. Различные классы могут иметь методы с тем же именем, конечно, но если они оба реализуют тот же интерфейс, то есть предположение, что они будут делать то же самое. Здесь они делают противоположные вещи!

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

-121--3612782-

PIGZ = параллельная реализация GZIP представляет собой полностью функциональную замену GZIP, которая использует несколько процессоров и несколько ядер к рукоятке при сжатии данных. http://www.zlib.net/pigz/ Это еще не Java --- Любые производители. Конечно, мир нуждается в его в Яве.

Иногда сжатие или декомпрессия - это большой CPU-потребитель, хотя он помогает I / O не быть узким местом.

Смотрите также данные (C ++) от HP Labs. PIGZ Параллелирует компрессию, в то время как декористы разрывает выход в большие сжатые блоки, которые декомпрессируются параллельно. Также имеет ряд других функций.

6
ответ дан 5 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: