我需要将多维双数组转换为锯齿状浮点数组.大小将从[2] [5]变为大约[6] [1024].
我很好奇如何循环并将双精度转换为浮点数将会执行并且它不太糟糕,对于[2] [5]数组大约225μs - 这是代码:
const int count = 5;
const int numCh = 2;
double[,] dbl = new double[numCh, count];
float[][] flt = new float[numCh][];
for (int i = 0; i < numCh; i++)
{
flt[i] = new float[count];
for (int j = 0; j < count; j++)
{
flt[i][j] = (float)dbl[i, j];
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果有更有效的技术,我想使用它们.我应该提一下,我只计时两个嵌套循环,而不是之前的分配.
经过多一点实验后,我认为99%的时间都是在循环上燃烧的,即使没有任务!
这将运行得更快,对于小数据而言,它不值得这样做Parallel.For(0, count, (j) =>,实际上对于非常小的数据运行速度要慢得多,这就是为什么我已经对该部分进行了评论.
double* dp0;
float* fp0;
fixed (double* dp1 = dbl)
{
dp0 = dp1;
float[] newFlt = new float[count];
fixed (float* fp1 = newFlt)
{
fp0 = fp1;
for (int i = 0; i < numCh; i++)
{
//Parallel.For(0, count, (j) =>
for (int j = 0; j < count; j++)
{
fp0[j] = (float)dp0[i * count + j];
}
//});
flt[i] = newFlt.Clone() as float[];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样运行得更快,因为[,]由于数组边界检查,双重访问双数组在.NET中真的很费力.这newFlt.Clone()意味着我们不是一直在修复和解除新的指针(因为这样做会有轻微的开销)
您需要使用unsafe代码标记运行它并使用/UNSAFE
但实际上你应该运行的数据接近5000 x 5000而不是5 x 2,如果某些东西需要少于1000毫秒,你需要添加更多的循环或增加数据,因为在那个级别cpu活动的一个小的峰值可以添加一个你的分析很多噪音.