Мой вопрос касается производительности Java по сравнению со скомпилированным кодом, например, C ++ / fortran / assembly в высокопроизводительных числовых приложениях.
Я знаю, что это спорная тема, но я ищу конкретные ответы / примеры. Также сообщество вики. Я задавал подобные вопросы и раньше, но, думаю, я выразился в общих чертах и не получил ответов, которые искал.
Умножение матрицы на матрицу двойной точности, широко известное как dgemm в библиотеке blas, позволяет достичь почти 100-процентной пиковой производительности ЦП (с точки зрения числа операций в секунду).
Есть несколько факторов, которые позволяют достичь этой производительности:
блокировка кеша для достижения максимальной локализации памяти
развертывание цикла для минимизации накладных расходов на управление
векторных инструкций, таких как SSE
предварительная выборка из памяти
гарантия отсутствия псевдонимов памяти
Я видел множество тестов, использующих ассемблер, C ++, Fortran, Atlas, поставщик BLAS (типичные случаи - матрица измерения 512 и выше).
С другой стороны, я слышал, что основные байтовые скомпилированные языки / реализации, такие как Java, могут быть быстрыми или почти такими же быстрыми, как машинно-компилируемые языки. Однако я не видел определенных ориентиров, показывающих, что это так. Напротив, кажется (из моего собственного исследования) скомпилированные байты языки намного медленнее.
У вас есть хорошие тесты умножения матриц-матриц для Java / C #?
может ли компилятор точно в срок (фактическая реализация, а не гипотетическая) генерировать инструкции, которые удовлетворяют перечисленным пунктам?
Спасибо
в отношении производительности:
каждый процессор имеет пиковую производительность, в зависимости от количества команд, которые процессор может выполнять в секунду. Например, современный процессор Intel с частотой 2 ГГц может достигать 8 миллиардов с двойной точностью добавления / умножения в секунду, что приводит к пиковой производительности 8 Гфлопс. Матрица-матричное умножение является одним из алгоритмов, который способен достичь почти полной производительности в отношении количества операций в секунду, основной причиной является более высокое соотношение вычислений к операциям с памятью (N^3/N^2)
. Числа меня интересуют, что-то на заказ N > 500
.
в отношении реализации: детали более высокого уровня, такие как блокировка, выполняются на уровне исходного кода. Оптимизация нижнего уровня выполняется компилятором, возможно, с подсказками компилятора относительно выравнивания / псевдонима. Байт-скомпилированная реализация также может быть написана с использованием блочного подхода, поэтому в принципе детали исходного кода для достойной реализации будут очень похожи.