Реализовать SIMD на java

136
05 января 2020, 11:20

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

SIMD (single instruction stream / multiple data stream) - одиночный поток команд и множественный поток данных. В архитектурах подобного рода сохраняется один поток команд, включающий, в отличие от предыдущего класса, векторные команды. Это позволяет выполнять одну арифметическую операцию сразу над многими данными - элементами вектора. Способ выполнения векторных операций не оговаривается, поэтому обработка элементов вектора может производится либо процессорной матрицей, как в ILLIAC IV, либо с помощью конвейера, как, например, в машине CRAY-1.

Answer 1

В Java-коде сейчас нет возможности явно указать компилятору место, где нужно использовать инструкции SIMD (JNI в расчет не берется), т.к. в байткод-инструкциях JVM нет такой команды. Однако, т.к. JVM перегоняет байткод в нативный, при этом анализируя его, то можно посоветовать JVM делать эту перегонку по-возможности используя инструкции SIMD. Это делается при помощи опции -XX:+UseSuperWord

Answer 2

В случае вычислений с использованием целочисленный типов JVM может преобразовать операции над значениями хранящихся в массивах в SIMD инструкции. Например такой код:

int[] x = ...
int[] y = ...
int[] z = ...
for (int i = 0; i < x.length; i++) {
    z[i] = x[i] * y[i];
}

может быть развернут в SIMD:

+-------+-------+-------+-------+
|   x3  |   x2  |   x1  |   x0  | xmm0
+-------+-------+-------+-------+
    *       *       *       *
+-------+-------+-------+-------+
|   y3  |   y2  |   y1  |   y0  | xmm1
+-------+-------+-------+-------+
    =       =       =       =
+-------+-------+-------+-------+
|   z3  |   z2  |   z1  |   z0  | xmm0
+-------+-------+-------+-------+

К сожалению это не сработает в случае вычислений с плавающей запятой (float), JVM не будет использовать SIMD, так как операции над float не ассоциативны, то есть 0.1 + (0.2 + 0.3) != (0.1 + 0.2) + 0.3.

Я не писал числодробилок и темой знаком плохо, но ранее мне попадались статьи вроде этой http://prestodb.rocks/code/simd/

В статье, поимо тестов производительности, приведен пример того, как можно убедится что JVM в момент исполнения генерирует нужный ассемблер, для этого есть ключ: -XX:CompileCommand=print,*BenchmarkSIMDBlog.increment где BenchmarkSIMDBlog эти имя класса из примера по ссылке, то есть его нужно будет поменять на свой.

READ ALSO
Как сделать проверку на то, что исключение действительно выбросится?

Как сделать проверку на то, что исключение действительно выбросится?

на примере функции water(), в которой есть проверка на пустую строку и null

142
мой пример сеттера (инкапсуляция)

мой пример сеттера (инкапсуляция)

Не пойму почему выводит:

118