2009-11-09 6 views
6

Мне интересно узнать о производительности числовых алгоритмов Java, скажем, например, умножение двойной точности матричной матрицы, используя новейшие машины JIT, например, для ручной настройки SSE C++/ассемблера или сопоставлений Fortran.Производительность Java в числовых алгоритмах

Я просмотрел веб-страницы, но большинство результатов пришло почти 10 лет назад, и я понимаю, что с тех пор Java развивается довольно много.

Если у вас есть опыт использования Java для приложений с числовой нагрузкой, вы можете поделиться своим опытом. Также насколько хорошо Java работает в ядрах, где петли относительно короткие, а доступ к памяти не очень однородный, но все еще находится в пределах кеша L1? Если такое ядро ​​выполняется несколько раз подряд, может ли JVM оптимизировать его во время выполнения?

Благодаря

+3

Лучше всего проверить его самостоятельно, поскольку сравнение с C++ будет жестким, так как это будет самым быстрым, и любое сравнение не будет иметь доступа к вашей конкретной реализации. –

+1

Примечание для других участников этой страницы: этот вопрос и большинство ответов - с 2009 года. JVM сейчас намного лучше, чем раньше. – eis

+0

Возможно, вам стоит взглянуть на ND4J, который поддерживает n-мерные массивы для Java. http://nd4j.org/benchmarking.html – tremstat

ответ

-4

Java использует Just In Time (JIT) компилятор для преобразования байт-кода на родной язык машины - поэтому первый раз она проходит через кодовый блок будет медленнее, но как только сегмент «разогрет «производительность будет эквивалентной. Короче говоря, числовые показатели довольно хорошие.

+1

JIT хороши, но их недостаточно, чтобы гарантировать хорошую численную производительность. –

0

Второе, что лучше всего проверить его самостоятельно, так как производительность будет несколько отличаться в зависимости от того, что вы делаете. Мне трудно поверить в ответ Шейна К. Мейсона о том, что производительность Java будет такой же, как производительность C++ или Fortran, так как даже C++ и Fortran на самом деле не сопоставимы для некоторых вычислительных алгоритмов.

У меня есть вычислительный код динамики жидкости, который я написал с использованием C++ и того же кода, по существу переведенного в Fortran. Я еще не уверен, почему пока, но версия Fortran примерно в два раза быстрее, чем версия на C++. Я бы предположил, что с такими функциями, как проверка границ и сборка мусора, Java будет медленнее, чем обе, но я не знаю, пока не проверю.

+0

Вы использовали ключевое слово ограничения в своем коде на C++? Компиляторы Fortran не должны гарантировать, что указатели на память не будут сглажены, тогда как компиляторы C++ должны предположить, что память сглажена, если не указано иное. Какие компиляторы вы использовали? Я запрограммировал свою программу на C++ с помощью встроенных функций, а компилятор Intel значительно быстрее, чем GCC, я полагаю, что инструкции Intel C++ лучше заказывают, поскольку сборка была в остальном очень похожа, за исключением заказа. – Anycorn

+0

Я смутно осознаю проблемы с псевдонимом, но пока не понимаю его. К сожалению, я еще не пытался ограничиться, но у меня не было времени потратить на это. Я использовал icpc и ifort (оба компилятора Intel) на linux с -O3. Обратите внимание, что моя точка зрения заключается не в том, что производительность C++ не может соответствовать fortran, а скорее вам нужно сравнивать реализации в дополнение к языкам. – notJim

+0

У Fortran также есть гораздо более расслабленная модель численных моделей, чем C++ - по умолчанию разрешено делать много скудных математических оптимизаций, которые вы получаете только на C/C++ с -ffast-math и аналогичными. Иногда это не имеет значения, и иногда это сделает ваши результаты менее точными. –

1

- ссылка на страницу перестрелки на языке программирования для java vs C++, которая даст вам сравнение скорости java на нескольких алгоритмах с интенсивным вычислением. Он также покажет вам, как выглядит высокопроизводительный Java-код. По большей части для этих нескольких конкретных тестов java занимала больше времени (но не более 2 или 3 раза) для запуска.

+0

Я не мог сразу сказать - это сравнение игнорирует разминки. Java все еще нуждается в _lot_ начальной работы, прежде чем достигать крейсерской скорости. –

+0

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

+0

@ Thorbjørn Ravn Andersen - 1) Читайте FAQ! 2) Обратите внимание, что программы работают в течение секунд, а не микросекунд! 3) Посмотрите на стационарные аппроксимации http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=javasteady&lang2=gpp&box=1 4) Прочитайте FAQ! о Java http://shootout.alioth.debian.org/u64q/faq.php#dynamic – igouy

1

Это происходит из .NET-стороны вещей, но я на 90% уверен, что это так и для Java. В то время как JIT будет использовать некоторые инструкции SSE, где это возможно, в настоящее время он не авто-векторизует ваш код при работе с, например, умножением матрицы. Ручной векторизованный C++ с использованием встроенных сборок компилятора/встроенной сборки определенно будет быстрее здесь.

0

Это может зависеть от того, что вы делаете в коде на C++.

Например, вы используете GPU? Редактировать Я забыл про jogl, поэтому Java может соревноваться здесь.

Распараллеливаются ли вы с использованием STM или разделяемой памяти, тогда Java не может конкурировать. Для ссылки на анализе параллельного умножения матриц: http://www.cs.utexas.edu/users/plapack/papers/ipps98/ipps98.html

Есть ли у вас достаточно памяти, чтобы сделать вычисление в памяти, так как сборщик мусор не будет нужен, и у вас доработан сборщик мусора для обеспечения оптимальной производительности ? Тогда, возможно, Java может быть конкурентоспособной.

Используете ли вы многоядерные процессоры, а C++ оптимизирован для использования этой архитектуры? Тогда Java не сможет конкурировать.

Используете ли вы несколько компьютеров, связанных друг с другом, тогда Java не сможет конкурировать.

Используете ли вы любую их комбинацию, то это будет зависеть от конкретной реализации.

Java не предназначен для конкурирования с программой C++ с ручной настройкой, но, сколько времени требуется для настройки, выполняете ли вы достаточные вычисления там, где это имеет значение? Java сможет дать некоторую разумную скорость, но с меньшим количеством работы, чем ручная настройка, но не большая часть улучшения по сравнению с просто кодом C++.

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

+0

Использование GPU? Как и в случае использования OpenGL? Если использование JOGL Java может хорошо конкурировать. –

+0

Вы правы, я исправил свой ответ, я забыл, что вы можете использовать jogl для работы GPU. –

1

Одна из самых слабых точек в java - это (собственные) операции с матрицей. Это связано с природой матриц Java:

  • Вы не можете объявить матрицу прямоугольной, т.е. каждая строка может иметь различное количество столбцов.

  • Матрица технически не является «матрицей двойников (или ints ...)», а массивом массивов .... Большая разница в том, что поскольку массивы являются объектами Java, вы можете назначить один и тот же объект массива более чем на 1 строку.

Эти два свойства делают невозможным стандартную матричную оптимизацию для компилятора.

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

+2

Я думаю, вы имеете в виду, что вы не можете объявить 2D-массив прямоугольным. Но вы, кажется, утверждаете, что самая буквальная и простая реализация матрицы в Java имеет некоторые проблемы. Почему это будет единственно возможная реализация? Если это не так, здесь не так много утверждений о «природе матриц Java». Что относительно библиотек матриц Java, таких как Colt? –

+0

Матрицы не всегда представлены таким образом. См. 'Java.awt.image.Ядро для примера матрицы, представленной 1D-массивом – finnw

+0

Проблема с такими библиотеками заключается в том, что весь доступ к матрице осуществляется с помощью методов. Вызов метода медленнее, чем доступ к массиву в целом, и они предотвращают определенные оптимизации компилятора. Например. 'for (int i = 0; i Carsten

1

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

После этого вы можете использовать JNI для вызова его с Java, если это необходимо.

Java не предназначен для высокопроизводительных арифметических расчетов, подобных этому. Если вы в зависимости от этого, я бы рекомендовал выбрать подходящий язык низкого уровня для его реализации. Или, альтернативно, вы можете написать часть, относящуюся к производительности, на языке низкого уровня, а затем подключить ее к интерфейсу Java с использованием JNI или другого метода IPC.

0

Являются ли эти вычисления интересными для вас - Быстрое преобразование Фурье, Якоби, последовательное за релаксацию, Интеграция Монте-Карло, Массив разреженной матрицы, Плотная матричная матрица LU?

Они составляют SciMark 2.0 composite benchmark, которые вы можете запускать в качестве апплета на вашем компьютере.

Существуют также программы ANSI C versions и Intel document (pdf) on optimizing and recompiling SciMark for C++.


Аналогично можно использовать The Java Grande Forum Benchmark Suite и the comparison C programs.

2

Я написал в Java достаточно большой и высокопроизводительный численный код (обычно хруст больших массивов двойных чисел).

Я нашел Java «достаточно хорошим» для быстрого численного расчета. Особенно, если учесть, что вы, как правило, не привязаны к процессору, - латентность памяти и понимание кэша, вероятно, будут вашей самой большой проблемой для больших наборов данных.

Тем не менее, вы по-прежнему можете использовать Java с оптимизированным вручную C/C++ кодом, который использует преимущества определенных векторизованных инструкций и т. Д. Или высоко настраиваемых макетов памяти. Таким образом, для самого быстрого кода вы можете рассмотреть возможность написания основного алгоритма в C/C++ и вызова его из Java с помощью JNI.

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

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