虽然问题提到了 C++,但我在 C#(.NET 4.5)中实现了 3x3 矩阵乘法 C=A*B,并在我的 64 位 windows 7 机器上运行了一些基本的时序测试并进行了优化。10,000,000 次乘法大约需要
- 0.556 秒,简单的实现和
- 0.874 秒,来自另一个答案的拉德曼代码。
有趣的是,laderman 代码比简单的方式要慢。我没有使用分析器进行调查,但我猜额外的分配比一些额外的乘法更昂贵。
似乎当前的编译器足够聪明,可以为我们做这些优化,这很好。这是我使用的天真的代码,供您参考:
public static Matrix3D operator *(Matrix3D a, Matrix3D b)
{
double c11 = a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31;
double c12 = a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32;
double c13 = a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33;
double c21 = a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31;
double c22 = a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32;
double c23 = a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33;
double c31 = a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31;
double c32 = a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32;
double c33 = a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33;
return new Matrix3D(
c11, c12, c13,
c21, c22, c23,
c31, c32, c33);
}
其中 Matrix3D 是一个不可变结构(只读双字段)。
棘手的事情是提出一个有效的基准,您可以在其中测量您的代码,而不是,编译器对您的代码做了什么(调试器有大量额外的东西,或者在没有实际代码的情况下进行优化,因为结果从未使用过)。我通常会尝试“触摸”结果,这样编译器就无法删除被测代码(例如检查矩阵元素是否与 89038.8989384 相等,如果相等则抛出)。但是,最后我什至不确定编译器是否会破解这个比较:)