首页 > 解决方案 > C++中cbrt()的优化

问题描述

我正在尝试提高用 C++ 编写的代码的速度。基于分析器,该函数cbrt()/cbrtf32x是我花费最多时间在/上(或更具体地说)的函数:

double test_func(const double &test_val){
    double cbrt_test_val = cbrt(test_val);
    return (1 - 1e-10*cbrt_test_val);
}

根据数据,我花费的时间cbrt()/cbrtf32x()是最接近成本昂贵的功能的三倍以上。因此,我想知道如何改进此功能,以及如何加快速度?输入值范围从1e181e30

标签: c++optimization

解决方案


如果您一次只做一个三次根,并且您想要准确的结果,那么几乎没有什么可以做的。

实际上,如果您可以将立方根计算提高 10-20% 以上——如果是这样的话——同时在数值上得到相同的结果,我会感到惊讶。(注意:我凭空得到了 10%-20% 的数字;这是一个观点,根本不是一个科学数字。)

如果您可以批量计算,您可能能够对操作进行 SIMD 操作,或对它们进行多线程处理,或者如果您对数据的分布有更多了解(或可以找到更多信息),您可能能够对它们进行排序并- 我不知道 - 也许计算一个增量立方根或其他东西。

如果您可以摆脱近似值,那么您可以做更多的事情。例如,您正在计算函数f(x) = 1 - cbrt(x) / 1e10,它与1 - cbrt(x / 1e30)将域 [1e18..1e30] 映射到范围 [0..0.9999] 的严格递减函数相同。有了y = x / 1e30f(y) = 1 - cbrt(y),现在y就在 [1e-12..1] 范围内,并且可以使用查找表预先计算和近似。

根据您需要三次根的次数、可以避免多少精度损失(这决定了表的大小)以及您是否可以对输入进行排序或分桶(以提高 LUT 的 CPU 缓存利用率查找)您可能会从中获得不错的速度提升。


推荐阅读