我正在使用信号处理库从硬件设备收集16384个双精度值。我收到的16384值是低通滤波器的输出。我想将采样降低10倍。换句话说,我希望每10个采样点中保留1分。因此,总的来说,它的工作原理如下:
低通滤波器完成后,我从库中获取了一个缓冲区。
然后我收集了10个这些缓冲区。
当所有10个缓冲区都收集到一个具有10 * 16384双精度的缓冲区中时,我然后从该缓冲区循环收集每10个double。结果是一个缓冲区有16384双打。这将用于其余的数据处理。
代码如下:
double[] rawData = new double[163840];
int bufferCount = 0;
private void genericReal2_ProcessData(object Sender, Mitov.SignalLab.ProcessRealNotifyArgs Args)
{
var realbuffer = Args.InBuffer; //get the buffer of processed doubles
var myData = realbuffer.ToArray(); //must be converted to an array since the data type is not quite an array of doubles.
Array.Copy(myData, 0, rawData, bufferCount * 16384, 16384);
bufferCount++;
if (bufferCount == 10)
{
bufferCount = 0;
int j = 0;
for (int i = 0; i < 163840; i += 10) //this loop takes 20ms
{
realbuffer[j] = rawData[i];
j++;
}
genericReal2.SendData(realbuffer); //send data off for further processing
}
}
for循环大约需要20毫秒才能运行,而其他一切大约需要20uS。
因此,有什么方法可以在不使用for循环的情况下提高整体性能吗?
更新************************** 我已经确定将循环中的所有处理时间都分配给realData给rawData。所以我将其更改如下:
private void genericReal2_ProcessData(object Sender, Mitov.SignalLab.ProcessRealNotifyArgs Args)
{
double[] finalBuffer = new double[16384];
var realbuffer = Args.InBuffer; //get the buffer of processed doubles
var myData = realbuffer.ToArray(); //must be converted to an array since the data type is not quite an array of doubles.
Array.Copy(myData, 0, rawData, bufferCount * 16384, 16384);
bufferCount++;
if (bufferCount == 10)
{
bufferCount = 0;
int j = 0;
for (int i = 0; i < 163840; i += 10)
{
finalBuffer[j] = rawData[i];
j++;
}
var pointer= realbuffer.Read();
//I can get a pointer to the realbuffer.
//It stores 8 bytes for every double value
how can I copy 16384 8 byte values from finalbuffer to realbuffer?
genericReal2.SendData(realbuffer); //send data off for further processing
}
答案 0 :(得分:1)
此问题已解决。我使用的库具有一个函数,该函数会将double []的所有值分配给它的内部实缓冲区
realbuffer.Equals(finalBuffer);
这需要50us ... 感谢您的所有帮助。
答案 1 :(得分:0)
您实际上正在得到所有东西,然后丢弃不必要的东西。如何在不进行复制的情况下删除这些文件,该如何做?我的意思是不是使用Array.Copy而是复制所需的内容;
int j = bufferCount * 16384;
for (int i = 0; i < 16384; i += 10)
{
realbuffer[j++] = rawData[i];
}
这样做,您将不需要在if语句中运行循环。
如果由于任何条件都无法更改代码的整体结构,则可以通过排序算法中使用的技术来提高循环性能。定义大小为163840 + 1的数组。为数组的最后一个位置分配一些值,例如-1,它将不在接收到的数据之内。并按如下所示更改循环,以减少执行循环中的比较次数;
for (int i = 0; i < rawData[i+=10 ] !=-1; )
{
realbuffer[j] = rawData[i];
j++;
}
希望有帮助。
答案 2 :(得分:-1)
您可以尝试将每个缓冲区放入字典,然后对每个缓冲区进行处理。从理论上讲,这应该更快,因为将并行处理数组。 20ms相当快,为什么需要这样的速度?
var buffers = new Dictionary<int, double[]>();
然后执行以下操作:
var myData = realbuffer.ToArray();
buffers.Add(bufferCount, myData);
if (bufferCount == 10)
{
Parallel.ForEach(buffers, (buffer) =>
{
//process buffer independently
});
}