3

我想提高我的动态链接库(DLL) 的性能。

为此,我想使用cos()sin()的查找表,因为我使用了很多。

由于我想要最大性能,我想创建一个从0 到 2PI的表,其中包含生成的 cos 和 sin 计算。

为了在精度方面取得良好的结果,我认为每个函数 1 mb 的表格是大小和精度之间的良好折衷。

我想知道如何在不使用外部文件(因为它是 DLL)的情况下创建和使用这些表:我想将所有内容保存在一个文件中。

此外,我不想在插件启动时计算 sin 和 cos 函数:它们必须计算一次并放入标准向量中。

但是我如何在 C++ 中做到这一点

EDIT1:来自 jons34yp 的代码非常适合创建矢量文件。

我做了一个小基准测试,发现如果您需要良好的精度和良好的速度,您可以在它们之间进行 250000 单位向量和线性插值,您将有 7.89E-11 最大误差(!),它是所有近似值中最快的我试过了(它比 sin() 快 12 倍以上(准确地说快了 13,296 倍)

4

3 回答 3

3

最简单的解决方案是编写一个单独的程序来创建一个.cc包含向量定义的文件。

例如:

#include <iostream>
#include <cmath>

int main()
{
    std::ofstream out("values.cc");

    out << "#include \"static_values.h\"\n"; 
    out << "#include <vector>\n";

    out << "std::vector<float> pi_values = {\n";
    out << std::precision(10);

    // We only need to compute the range from 0 to PI/2, and use trigonometric
    // transformations for values outside this range.
    double range = 3.141529 / 2;
    unsigned num_results = 250000;

    for (unsigned i = 0; i < num_results; i++) {
        double value = (range / num_results) * i;
        double res = std::sin(value);

        out << "    " << res << ",\n";
    }
    out << "};\n"
    out.close();
}

请注意,这不太可能提高性能,因为这种大小的表可能不适合您的 L2 缓存。这意味着大部分三角函数计算都需要访问 RAM;每个这样的访问大约花费数百个 CPU 周期。

顺便说一句,您是否看过近似的 SSE SIMD 三角函数库。这对他们来说似乎是一个很好的用例。

于 2013-08-30T11:34:40.930 回答
2

您可以使用预计算而不是将已经预计算的它们存储在可执行文件中:

double precomputed_sin[65536];

struct table_filler {
    table_filler() {
        for (int i=0; i<65536; i++) {
            precomputed_sin[i] = sin(i*2*3.141592654/65536);
        }
    }
} table_filler_instance;

这样,该表在程序启动时只计算一次,并且它仍然位于固定的内存地址。之后,tsin可以tcos内联实现为

inline double tsin(int x) { return precomputed_sin[x & 65535]; }
inline double tcos(int x) { return precomputed_sin[(x + 16384) & 65535]; }
于 2013-08-30T11:58:17.380 回答
0

这类问题的通常答案是编写一个小程序,该程序生成一个包含表中值的 C++ 源文件,并将其编译到您的 DLL 中。但是,如果您正在考虑包含 128000 个条目的表(128000 个双精度数为 1MB),那么您可能会遇到编译器中的一些内部限制。在这种情况下,您可能会考虑将值作为内存转储写入文件,并mmap在加载 DLL 时对该文件进行 ing。(在 Windows 下,我认为您甚至可以将第二个文件放入 DLL 文件的第二个流中,这样您就不必分发第二个文件。)

于 2013-08-30T11:42:21.847 回答