Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
循环优化的C语言_C_For Loop_Optimization - Fatal编程技术网

循环优化的C语言

循环优化的C语言,c,for-loop,optimization,C,For Loop,Optimization,我正在努力学习如何优化我的c代码,所以我在互联网上找到了一些文章,并重新设计了我的函数,以便它能够更快地执行。当我在没有优化标志的情况下编译它时,它可以工作(第二个函数比第一个函数快12%),但当我使用gcc-O3时,第二个函数要慢得多(大约50%)。你知道为什么吗? 谢谢你的帮助 第一个功能: typedef struct { double *data; int rows; int columns; } Matrix; Matrix *matrixMultiplica

我正在努力学习如何优化我的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;
}

这是因为编译器优化是基于模式识别的。您的编译器知道大量典型的代码模式,并且知道如何转换它们以生成更快的代码。然而,虽然这个代码模式库相当广泛,但它是有限的

第一个函数将规范的
用于(inti=0;i
循环控制。您可以打赌,任何值得一试的编译器都有这样的模式,为循环控制生成接近最优的代码

第二个函数使用了人类代码中罕见的模式。虽然我个人喜欢这种模式的简洁性,但有许多程序员发现它太神秘而无法使用。显然,编译器没有为此提供优化器模式,因此生成的代码没有得到充分优化



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

如果要比较具有相同功能的两种不同算法,请确保使用相同的数据和数据结构。否则,比较是没有意义的。我对相同的数据使用它,但我更改了数据结构,因为我读取了数据,所以当比较时,我更应该使用浮点和无符号整数possible@PatrikDobiáš因为一个使用float,另一个使用double,所以没有使用相同的数据。@应该使用正确的类型。例如,对于索引和大小,您有
size\u t
。在现代系统中,使用浮点数时可能会受到惩罚,因为它们可能必须转换为双倍或更大的类型。维度有多大?是的,编译器非常好。我曾经用“C”编写了一些加密代码,并对其进行了优化编译。然后,作为一名多年的汇编程序员,我查看了生成的代码。是的,我可以保存一条指令,因为我可以使用一个通常保留的寄存器,可能速度会提高2%。因为这段代码在一段时间内24/7运行了几个月,这段时间可能花得很好。总的来说,编译器在优化方面做得非常出色,这并不值得为此付出努力。