首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在CFD C程序中优化决策

如何在CFD C程序中优化决策
EN

Stack Overflow用户
提问于 2019-07-09 15:44:25
回答 1查看 65关注 0票数 3

我想优化CFD代码中不同函数的使用,用户可以通过程序读取的配置文件在运行时选择这些函数。

我想出了一个最小的工作示例,其中有两个单独的函数,只有一个输入。一个对输入进行平方,一个对输入进行立方体。通过命令行选项,用户可以选择使用哪个函数。在for循环中,正方形/立方体代码(它计算x^2或x^3的0到1之间的积分,取决于所选择的函数)并输出结果。第一个变体只是for循环(case1)中的开关情况。我尝试的第二件事是一个函数指针,它在循环(case2)之前设置。我做的第三件事是只有选择地编译用户打算在使用预处理器命令(case3)时使用的函数。

case1:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

double f_square(double x) {return x * x;}

double f_cube(double x) {return x * x * x;}

int main(int argc, char *argv[])
{
    double x;
    double sum = 0;
    double del_x = 4e-10;

    printf("Speed test -- no optimisation\n");

    clock_t startClock = clock();
    for (x = 0; x < 1; x += del_x) {
        switch (argv[1][0]) {
        case '2':
            sum += f_square(x) * del_x;
            break;
        case '3':
            sum += f_cube(x) * del_x;
            break;
        default:
            printf("Invalid choice! Abort\n");
            exit(1);
        }
    }
    clock_t endClock = clock();

    printf("Int_{0}^{1} x^%c: %.8g\n", argv[1][0], sum);
    printf("Execution time: %.6f\n", (endClock - startClock) / (double)CLOCKS_PER_SEC);
}

case2:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

double f_square(double x) {return x * x;}

double f_cube(double x) {return x * x * x;}

int main(int argc, char *argv[])
{
    double x;
    double sum = 0;
    double del_x = 4e-10;
    double (*f)(double);

    printf("Speed test -- function pointers\n");

    switch (argv[1][0]) {
    case '2':
        f = &f_square;
        break;
    case '3':
        f = &f_cube;
        break;
    default:
        printf("Invalid choice! Abort\n");
        exit(1);
    }

    clock_t startClock = clock();
    for (x = 0; x < 1; x += del_x) {
        sum += f(x) * del_x;
    }
    clock_t endClock = clock();

    printf("Int_{0}^{1} x^%c: %.8g\n", argv[1][0], sum);
    printf("Execution time: %.6f\n", (endClock - startClock) / (double)CLOCKS_PER_SEC);
}

case3:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef SQUARE
double f(double x) {return x * x;}
#endif

#ifdef CUBE
double f(double x) {return x * x * x;}
#endif

int main(void)
{
    double x;
    double sum = 0;
    double del_x = 4e-10;

    printf("Speed test -- selective compilation\n");

    clock_t startClock = clock();
    for (x = 0; x < 1; x += del_x) {
        sum += f(x) * del_x;
    }
    clock_t endClock = clock();

    #ifdef SQUARE
    printf("Int_{0}^{1} x^2: %.8g\n", sum);
    #endif
    #ifdef CUBE
    printf("Int_{0}^{1} x^3: %.8g\n", sum);
    #endif
    printf("Execution time: %.6f\n", (endClock - startClock) / (double)CLOCKS_PER_SEC);
}

在测量执行时间时,我发现了一些奇怪的东西:

  • 使用O0,我得到了我预期的发行版,case3是最快的,其次是case2,然后是case1
  • 对于O1-O3,case2的表现总是比case1和case3差得多。

下面是比较执行时间的一些图像

这让我感到困惑,我想知道我能做些什么才能在不失去性能的情况下使用函数指针,因为出于灵活性的原因,我真的想使用函数指针。

=>为什么函数指针这么慢?

我想补充的是,我不是一名软件工程师,而是一名航空航天工程专业的学生,遗憾的是,我们没有学到很多编程课程,所以每一个细节都可能会有所帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-09 16:28:02

下面是两个类似函数的反汇编视图:https://c.godbolt.org/z/l24Zhl

注意,对于-O2,第一个方法内联了对f_cubef_square的调用(注意没有调用程序集中的函数),但是第二个版本没有。

最有可能的是,由于处理器上的分支预测,第一个版本会进一步加速.

您是否分析过您的代码并发现此区域是一个瓶颈?请记住,通过首先优化使用最多的代码,可以获得最大的速度增益。记住:首先让它起作用,然后使它快速。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56956260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档