gpt4 book ai didi

c - 替换极其缓慢的 pow() 函数

转载 作者:太空狗 更新时间:2023-10-29 16:24:51 26 4
gpt4 key购买 nike

我们有一个 CFD 求解器,在运行模拟时,我们发现它在某些机器上运行速度非常慢,但在其他机器上则不然。使用 Intel VTune,发现以下行是问题所在(在 Fortran 中):

RHOV= RHO_INF*((1.0_wp - COEFF*EXP(F0)))**(1.0_wp/(GAMM - 1.0_wp))

使用 VTune 深入研究,问题被追踪到 call pow 装配线,当追踪堆栈时,它显示它正在使用 __slowpow()。经过一番搜索,this page出现提示同样的事情。

在 libc 版本 2.12 的机器上,模拟耗时 18 秒。在 libc 版本 2.14 的机器上,模拟耗时 0 秒。

根据上述页面上的信息,当 pow() 的基数接近 1.0 时,就会出现问题。所以我们做了另一个简单的测试,我们在 pow() 之前按任意数字缩放基数,然后在 pow() 调用之后除以提升到指数的数字.这也将 libc 2.12 的运行时间从 18 秒减少到 0 秒。

但是,将它放在我们执行 a**b 的所有代码中是不切实际的。如何替换 libc 中的 pow() 函数?例如,我希望由 Fortran 编译器生成的装配线 call pow 调用我们编写的自定义 pow() 函数来执行缩放,调用 libc pow() 然后除以缩放比例。如何创建一个对编译器透明的中间层?

编辑

为了澄清,我们正在寻找类似(伪代码)的东西:

double pow(a,b) {
a *= 5.0
tmp = pow_from_libc(a,b)
return tmp/pow_from_libc(5.0, b)
}

是否可以从 libc 加载 pow 并在我们的自定义函数中重命名它以避免命名冲突?如果 customPow.o 文件可以从 libc 重命名 pow,如果其他事情仍然需要 libc,会发生什么情况?这会导致 customPow.o 中的 pow 和 libc 中的 pow 之间发生命名冲突吗?

最佳答案

好吧,等一下。库调用 __slowpow() 并不是为了玩弄你;它之所以调用 __slowpow(),是因为它认为需要额外的精度才能为您提供的值提供准确的结果(在本例中,基数非常接近 1,阶数为 1)。如果您关心此计算的准确性,则在尝试解决它之前,您应该了解这是为什么以及它是否重要。对于(比如)大的负 F0 可能是这样的情况,这整个事情可以安全地四舍五入为 1;也可能不会,这取决于稍后对该值所做的操作。如果您需要 1.d0 减去此结果,您将需要更高的精度。

关于c - 替换极其缓慢的 pow() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9272155/

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