【问题标题】:Fast 4x4 matrix multiplication in Java with NIO float buffers带有 NIO 浮点缓冲区的 Java 中的快速 4x4 矩阵乘法
【发布时间】:2011-02-17 08:32:31
【问题描述】:

我知道有很多这样的问题,但我找不到一个特定于我的情况的问题。我将 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 实现(比如 Android 中的 OpenGL ES 的东西)为此提供了本机代码,但其他的则没有。所以我想为这些实现提供一个通用的乘法方法。

【问题讨论】:

    标签: java math matrix nio


    【解决方案1】:

    真正的答案当然是测试不同的实现并检查哪一个最快。

    我的猜测是,未经测试,由于矩阵非常小,手动扩展循环会产生最快的代码。例如。像

    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$。

    【讨论】:

    • 请注意,JIT 编译器非常擅长在必要时展开循环,因此您可能会发现其中没有太多内容。
    【解决方案2】:

    如果支持该操作,请通过FloatBuffer.array()。然后通过该数组执行必要的乘法,并返回结果矩阵。

    查看GameDev.net - Matrix Math 了解确切的计算结果。

    如果你想进一步优化它,你可以试试Strassens Algorithm。你甚至不需要填充你的矩阵,因为它们是正方形的,大小是 2 的幂。

    【讨论】:

    • 正如关于 Strassen 的维基百科文章所说:“Strassen 算法的实际实现切换到对于足够小的子矩阵的矩阵乘法标准方法,它们更有效。Strassen 算法的特定交叉点是效率更高取决于具体的实现和硬件。据估计,Strassen 的算法对于宽度从 32 到 128 的矩阵来说更快,以优化实现。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2011-11-30
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多