c - C for循环优化

标签 c for-loop optimization

我试图学习如何优化我的C代码,所以我在网上找到了一些文章并重新制作了函数,以便可以更快地执行。当我在没有优化标志的情况下进行编译时,它可以工作(第二个函数比第一个函数快约12%),但是当我与gcc -O3一起使用时,第二个函数要慢得多(约50%)。你知道为什么吗?
谢谢你的帮助。

第一个功能:

typedef struct {
    double *data;
    int rows;
    int columns;
} Matrix;

Matrix *matrixMultiplication(Matrix *a, Matrix *b) {
    if(a->columns != b->rows)
        return NULL;
    Matrix *matrix = createMatrix(a->rows, b->columns);
    set(0, matrix);
    for(int i = 0; i < matrix->rows; i++) {
        for(int j = 0; j < a->columns; j++) {
            for(int k = 0; k < b->columns; k++) {
                matrix->data[i * matrix->columns + k] += a->data[i * a->columns + j] * b->data[j * b->columns + k];
            }
        }
    }
    return matrix;
}


第二功能:

typedef struct {
    float *data;
    unsigned int rows;
    unsigned int columns;
} Matrix_2;

unsigned int matrixMultiplication_2(Matrix_2 *a, Matrix_2 *b, Matrix_2 **c) {
    Matrix_2 *matrix;
    if(a->columns != b->rows)
        return 0;
    createMatrix_2(a->rows, b->columns, &matrix);
    set_2(0, matrix);
    for(unsigned int i = matrix->rows; i--;) {
        for(unsigned int j = a->columns; j--;) {
            for(unsigned int k = b->columns; k--;) {
                matrix->data[i * matrix->columns + k] += a->data[i * a->columns + j] * b->data[j * b->columns + k];
            }
        }
    }
    *c = matrix;
    return 1;
}

最佳答案

这是因为编译器优化基于模式识别。您的编译器知道很多典型的代码模式,并且知道如何转换它们以产生更快的代码。但是,尽管此代码模式库相当广泛,但它是有限的。

第一个函数使用规范的for(int i = 0; i < count; i++)循环控件。您可以打赌,任何值得赞扬的编译器都为此提供了一种模式,可以为循环控制产生接近最佳的代码。

第二个功能使用的模式在人工代码中很少见。尽管我个人很喜欢这种模式的简洁性,但仍有许多程序员认为它过于神秘而无法使用。显然,您的编译器没有为此提供优化器模式,因此生成的代码没有得到完全优化。



当C仍只是高级汇编程序时,用for(int i = 0; i < count; i++)替换for(int i = count; i--;)这样的优化非常有用。但是长期以来,编译器优化已将代码转换变成过于复杂的野兽,无法通过此类技巧进行优化。今天,大多数优化都需要在算法层面上完成。翻译级别的优化通常应留给编译器,并通过编写编译器可以优化的规范代码来促进。

关于c - C for循环优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51350877/

相关文章:

c - strn*() 与 str*() 相比有多快?

c - C语言的字数统计程序

c - 基本C,输出不正确

JavaScript 函数作为 For 循环中的变量

perl - perl 中的 for 循环

python - 访问字符串列表中的每个字符,避免嵌套 for 循环

optimization - Prolog 递归的顺序重要吗?

c - 添加到字符串前面

c - 在不同迭代中使用 fscanf/fgets 读取文件时随机崩溃

php - 哪一个在资源方面成本更低?