Быстрое умножение матриц 4x4 в Java с плавающими буферами NIO

Я знаю, что таких вопросов МНОГО, но я не могу найти ни одного конкретного для моей ситуации. У меня есть матрицы 4x4, реализованные как плавающие буферы NIO (эти матрицы используются для OpenGL). Теперь я хочу реализовать метод умножения, который умножает матрицу A на матрицу B и сохраняет результат в матрице C. Таким образом, код может выглядеть так:

class Matrix4f
{
    private FloatBuffer buffer = FloatBuffer.allocate(16);

    public Matrix4f multiply(Matrix4f matrix2, Matrix4f result)
    {
        {{{result = this * matrix2}}} <-- I need this code

        return result;
    }
}

Каков самый быстрый код для выполнения этого умножения? Некоторые реализации OpenGL (например, OpenGL ES в Android) предоставляют собственный код для этого, а другие — нет. Поэтому я хочу предоставить общий метод умножения для этих реализаций.


person kayahr    schedule 09.05.2010    source источник


Ответы (2)


Реальный ответ, конечно, состоит в том, чтобы протестировать различные реализации и проверить, какая из них самая быстрая.

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

result[0][0] = this[0][0] * matrix2[0][0] + this[0][1] * matrix2[1][0] 
             + this[0][2] * matrix2[2][0] + this[0][3] * matrix2[3][0];
result[0][1] = // ... and so forth

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

person janneb    schedule 09.05.2010
comment
Обратите внимание, что JIT-компилятор довольно хорошо разворачивает циклы там, где это необходимо, поэтому вы можете обнаружить, что в нем не так уж много. - person Neil Coffey; 09.05.2010

Пройдите через FloatBuffer. .array(), если эта операция поддерживается. Затем просто выполните необходимые умножения через этот массив и верните результирующую матрицу.

Точные вычисления см. на странице GameDev.net — Matrix Math.

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

person aioobe    schedule 09.05.2010
comment
Как говорится в статье в Википедии о Штрассене: «Практические реализации алгоритма Штрассена переключаются на стандартные методы матричного умножения для достаточно малых подматриц, для которых они более эффективны. Конкретная точка пересечения, для которой алгоритм Штрассена более эффективен, зависит от конкретной реализации и аппаратного обеспечения. Было подсчитано, что алгоритм Штрассена работает быстрее для матриц шириной от 32 до 128 для оптимизированных реализаций. - person janneb; 09.05.2010