我的代码如下,在主函数中,我回想起Mat_product函数大约223440次,在整个运行时中使用179ns23%

struct Matrix_SE3 {
    float R[3][3];
    double P[3];  //here i need use double type.
};

struct Matrix_SE3 Mat_product(struct Matrix_SE3 A, struct Matrix_SE3 B) {
    struct Matrix_SE3 result = { { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, { 0,
            0, 0 } };
    for (int i = 0; i < 3; i++) {
        result.P[i] += A.P[i];
        for (int j = 0; j < 3; j++) {
            result.P[i] += A.R[i][j] * B.P[j];
            for (int k = 0; k < 3; k++)
                result.R[i][j] += A.R[i][k] * B.R[k][j];
        }
    }
    return result;
}


其中$ R $是旋转矩阵,而$ P $表示位置,该函数是在两个特殊的欧几里得组$ SE(3)$矩阵相乘后得出的,并返回$ SE(3)$矩阵。

也许这是Optimized matrix multiplication in C的副本,不同之处是我的代码使用struct描述矩阵,这会影响计算效率吗?

最佳答案

不确定代码中的P和R par是多少,但是您永远不要使用ijk排序进行矩阵乘法。

由于行的顺序较大,因此在访问内部循环中的B.R [k] [j]时,即使使用较小的矩阵,多次访问也会导致高速缓存未命中,从而显着降低性能。

执行矩阵乘法的正确方法是按照ikj顺序进行迭代。

for (int i = 0; i < 3; i++) {
    double r;
    result.P[i] += A.P[i];
    for (int k = 0; k < 3; k++) {
        r=A.R[i][k];
        for (int j = 0; j < 3; j++) {
            result.P[i] += A.R[i][j] * B.P[j];
            result.R[i][j] += r * B.R[k][j];
        }
    }
}


所有访问将按行主要顺序正确执行,并将受益于缓存行为。

并且不要忘记使用-O3优化。大多数编译器将使用sse / avx指令来优化代码。

关于c - 有什么方法可以优化C语言中的矩阵乘法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54305015/

10-11 23:04
查看更多