1

我正在优化 C 中的矩阵乘法程序。目前我的代码是这样的:

首先我有一个矩阵结构:

typedef struct
{
    float ** element;
} matrix;

然后我编写了一个矩阵乘法例程,并通过转置第二个矩阵并使用 simd 对其进行优化:

void mulMatrices(matrix a, matrix b, matrix result)
{

    int i, j, k;
    long long before, after;

    before = wall_clock_time();

    transpose_matrix(&b);

    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
        {
            __m128 vresult = _mm_setzero_ps();
            for(k = 0; k < size; k += 4)
            {
                vresult = _mm_add_ps(vresult, _mm_mul_ps(_mm_load_ps(&(a.element[i][k])), _mm_load_ps(&(b.element[j][k]))));
            }
            result.element[i][j] = vresult[0] + vresult[1] + vresult[2] + vresult[3];
        }

    after = wall_clock_time();
}

最后我写了一个工作函数来初始化矩阵并调用乘法函数

void work()
{
    matrix a, b, result;

    // Initialise matrices

    // Perform sequential matrix multiplication
    mulMatrices(a, b, result);

    // Print the result matrix
    //print_matrix(result);

}

我的主要功能如下:

int main(int argc, char ** argv)
{   
    // Multiply the matrices
    work();
    return 0;
}

我已经可以用这些东西取得相当令人满意的结果了。但是我发现,如果我把所有的东西都精简了,把所有的代码都移到主函数中,它会快 100 倍以上。矩阵的大小至少为 1024 * 1024。我想这与调用堆栈有关,但我不明白。有人可以解释一下。谢谢

4

1 回答 1

1

您可能会遇到别名问题。基本上,当通过指针编辑值时,编译器不知道您是否修改了它已经读取的内容,因此每次都必须从内存中重新读取值。

这是描述该问题的白皮书:ftp: //ftp.sgi.com/sgi/audio/audio.apps/dev/aliasing.html

通过将所有代码直接移动到您的 main 中,您已经删除了别名,从而大大提高了性能。

于 2013-10-04T19:00:44.100 回答