gpt4 book ai didi

c - 如何优化 CFD C 代码中的决策

转载 作者:太空狗 更新时间:2023-10-29 15:31:11 26 4
gpt4 key购买 nike

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

我想出了一个最小的工作示例,其中有两个单独的函数和一个输入。一种将输入平方,一种将其立方。通过命令行选项,用户可以选择要使用的功能。在 for 循环中编写正方形/立方体一堆数字的代码(它计算 x^2 或 x^3 从 0 到 1 的积分,具体取决于选择的函数)并输出结果。第一个变体只是 for 循环 (case1) 中的一个 switch case。我尝试的第二件事是一个函数指针,它被设置在循环之前 (case2)。我做的第三件事是有选择地只编译用户打算使用预处理器命令(案例 3)使用的函数。

案例一:

#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);
}

案例2:

#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);
}

案例3:

#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 差很多

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

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

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

我想补充一点,我不是软件工程师,而是一名航空航天工程专业的学生,​​遗憾的是我们没有太多的编程类(class),所以每一个细节都可能有所帮助。

最佳答案

这是相似功能的两个实现的反汇编 View :https://c.godbolt.org/z/l24Zhl

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

很可能,第一个版本由于 Branch Prediction 而进一步加速在处理器上。

您是否分析过您的代码并发现该区域是一个瓶颈?请记住,首先优化最常用的代码可以最大程度地提高速度。请记住:先使其工作,然后再使其快速。

关于c - 如何优化 CFD C 代码中的决策,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56956260/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com