- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们有一个 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/
可能是一个精彩的故事——QTP 似乎无缘无故地浪费了我们的工作时间: 考虑这个脚本,它有一个包含 26 列的全局行的数据表,名为“A”到“Z”,填充了任意值: Print "Started" Serv
我是一名优秀的程序员,十分优秀!