我希望在编译时制作一个余弦表。有没有办法在没有硬编码的情况下做到这一点?
8 回答
为什么不硬编码呢?我不知道他们正在计划的余弦函数的结果有任何变化,再过 100 年左右也不会。
我不相信预先计算正弦表会提高性能。我建议:
- 对调用 fcos() 的应用程序进行基准测试以确定它是否足够快。如果是,请停在这里。
- 如果它确实太慢,请考虑使用 -ffast-math 如果它可以接受您的使用。
查找表,尤其是大型查找表,会增加需要保存在 CPU 缓存中的程序的大小,从而降低其命中率。这反过来会减慢应用程序的其他部分。
我假设你在一个非常紧密的循环中这样做,因为这是唯一可能无论如何都可能重要的情况。
如果您确实发现使用查找表是有益的,为什么不在运行时预先计算呢?它对启动时间几乎没有任何影响(除非它是一个 huuuuuge )。实际上在运行时执行它可能会更快,因为您的 CPU 执行正弦波的速度可能比您的磁盘加载浮点数的速度更快。
使用 C++,您可以使用模板元编程在运行时生成查找表。
现在,这是一个标准的 C 技巧,可能会也可能不会完成您想要的。
- 编写一个程序(比如 cosgen),生成余弦表 C 语句(即您想要的代码)。
- 运行 cosgen 并将输出(c 代码)转储到文件中,例如 cos_table.c
- 在您的主程序中,使用 #include "cos_table.c" 将表插入您想要的位置。
您可以使用您喜欢的任何脚本语言生成它并包含结果。每当您更改源代码时,请使用 make 让脚本语言执行其操作。它被硬编码为 C 但不是你,真的。
借助计算机的魔力,看似不可能的事情变为可能:
#include <stdio.h>
#include <math.h>
#define MAX_ANGLE 90
double kinopiko_krazy_kosines[MAX_ANGLE];
int main ()
{
int i;
for (i = 0; i <= 90; i++) {
double angle = (M_PI * i) / (2.0*90.0);
kinopiko_krazy_kosines[i] = cos (angle);
printf ("#define cos_%d %f\n", i, kinopiko_krazy_kosines[i]);
}
}
既然您针对的是 Cell,那么您可能针对的是 SPE?它们确实有适当的 FP 支持,实际上是矢量化的,但没有大的工作记忆。出于这个原因,使用表实际上是一个坏主意——你牺牲了非常有限的资源。
我会创建一个硬编码的查找表 - 曾经使用脚本语言 - 但我不确定它是否会比仅使用标准数学库更快。
我想这取决于表的大小,但我怀疑让 FPU 进行计算可能比访问内存更快。因此,一旦您获得了表格解决方案,我会对其进行基准测试,看看它是否比标准功能更快。
波表是要走的路。您可以按照建议对其进行硬编码,或在应用程序启动期间运行它。