gpt4 book ai didi

c# - 使用预计算平移数组的快速正弦/余弦

转载 作者:可可西里 更新时间:2023-11-01 03:13:28 26 4
gpt4 key购买 nike

我有以下代码使用预先计算的内存表执行 Sin/Cos 函数。在下面的例子中,表格有 1024*128 个项目,涵盖了从 0 到 2pi 的所有 Sin/Cos 值。我知道我可以使用 Sin/Cos 对称性并仅保留 1/4 的值,但在计算值时我会有更多的“如果”。

private const double PI2 = Math.PI * 2.0; 
private const int TABLE_SIZE = 1024 * 128;
private const double TABLE_SIZE_D = (double)TABLE_SIZE;
private const double FACTOR = TABLE_SIZE_D / PI2;

private static double[] _CosineDoubleTable;
private static double[] _SineDoubleTable;

设置翻译表

private static void InitializeTrigonometricTables(){
_CosineDoubleTable = new double[TABLE_SIZE];
_SineDoubleTable = new double[TABLE_SIZE];

for (int i = 0; i < TABLE_SIZE; i++){
double Angle = ((double)i / TABLE_SIZE_D) * PI2;
_SineDoubleTable[i] = Math.Sin(Angle);
_CosineDoubleTable[i] = Math.Cos(Angle);
}
}

该值是以弧度为单位的 double 值。

Value %= PI2;  // In case that the angle is larger than 2pi
if (Value < 0) Value += PI2; // in case that the angle is negative
int index = (int)(Value * FACTOR); //from radians to index and casted in to an int
double sineValue = _SineDoubleTable[index]; // get the value from the table

我正在寻找一种更快的方法来做到这一点。上面 4 行大约占整个过程的 25%(执行了数十亿次)。

最佳答案

您可以尝试使用不安全代码来消除数组边界检查。
但即使是不安全的优化版本似乎也不会接近 Math.Sin。 .

基于 1'000'000'000 次随机值迭代的结果:

(1) 00:00:57.3382769  // original version
(2) 00:00:31.9445928 // optimized version
(3) 00:00:21.3566399 // Math.Sin

代码:

static double SinOriginal(double Value)
{
Value %= PI2;
if (Value < 0) Value += PI2;
int index = (int)(Value * FACTOR);
return _SineDoubleTable[index];
}

static unsafe double SinOptimized(double* SineDoubleTable, double Value)
{
int index = (int)(Value * FACTOR) % TABLE_SIZE;
return (index < 0) ? SineDoubleTable[index + TABLE_SIZE]
: SineDoubleTable[index];
}

测试程序:

InitializeTrigonometricTables();
Random random = new Random();

SinOriginal(random.NextDouble());
var sw = System.Diagnostics.Stopwatch.StartNew();
for (long i = 0; i < 1000000000L; i++)
{
SinOriginal(random.NextDouble());
}
sw.Stop();
Console.WriteLine("(1) {0} // original version", sw.Elapsed);

fixed (double* SineDoubleTable = _SineDoubleTable)
{
SinOptimized(SineDoubleTable, random.NextDouble());
sw = System.Diagnostics.Stopwatch.StartNew();
for (long i = 0; i < 1000000000L; i++)
{
SinOptimized(SineDoubleTable, random.NextDouble());
}
sw.Stop();
Console.WriteLine("(2) {0} // optimized version", sw.Elapsed);
}

Math.Sin(random.NextDouble());
sw = System.Diagnostics.Stopwatch.StartNew();
for (long i = 0; i < 1000000000L; i++)
{
Math.Sin(random.NextDouble());
}
sw.Stop();
Console.WriteLine("(3) {0} // Math.Sin", sw.Elapsed);

关于c# - 使用预计算平移数组的快速正弦/余弦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2088194/

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