围绕对角线镜像位矩阵的性能改进 [英] Performance improvement for mirroring bit matrix around the diagonal

查看:68
本文介绍了围绕对角线镜像位矩阵的性能改进的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码可以管理从传感器阵列接收到的数据.控制传感器的PIC并行使用8个SAR-ADC来读取4096个数据字节.这意味着它将读取前8个字节的最高有效位.然后读取它们的第二位,依此类推,直到第八位(最低有效位).

I have some code that manages data received from an array of sensors. The PIC that controls the sensors uses 8 SAR-ADCs in parallel to read 4096 data bytes. It means it reads the most significant bit for the first 8 bytes; then it reads their second bit and so on until the eighth (least significant bit).

基本上,它每读取8个字节,就会创建(并将其发送到计算机)8个字节,如下所示:

Basically, for each 8 bytes it reads, it creates (and sends forth to the computer) 8 bytes as follows:

// rxData[0] = MSB[7] MSB[6] MSB[5] MSB[4] MSB[3] MSB[2] MSB[1] MSB[0]
// rxData[1] = B6[7] B6[6] B6[5] B6[4] B6[3] B6[2] B6[1] B6[0]
// rxData[2] = B5[7] B5[6] B5[5] B5[4] B5[3] B5[2] B5[1] B5[0]
// rxData[3] = B4[7] B4[6] B4[5] B4[4] B4[3] B4[2] B4[1] B4[0]
// rxData[4] = B3[7] B3[6] B3[5] B3[4] B3[3] B3[2] B3[1] B3[0]
// rxData[5] = B2[7] B2[6] B2[5] B2[4] B2[3] B2[2] B2[1] B2[0]
// rxData[6] = B1[7] B1[6] B1[5] B1[4] B1[3] B1[2] B1[1] B1[0]
// rxData[7] = LSB[7] LSB[6] LSB[5] LSB[4] LSB[3] LSB[2] LSB[1] LSB[0]

系统读取并处理的所有4096字节都重复此模式.

This pattern is repeated for all the 4096 bytes the system reads and I process.

想象一下,每读取8个字节是分开进行的,那么我们可以将它们看作是一个8×8的位数组.我需要围绕从左下角(LSB [7])到右上角(MSB [0])的对角线镜像此数组.完成此操作后,所得的8 x 8位数组将在其行中包含从传感器读取的正确数据字节.我曾经在PIC控制器上执行此操作,使用的是左移等,但是这使系统的运行速度大大降低.因此,现在可以使用以下代码在我们处理数据的计算机上执行此操作:

Imagine that each 8 bytes read are taken separately, we can then see them as an 8-by-8 array of bits. I need to mirror this array around the diagonal going from its bottom-left (LSB[7]) to its top-right (MSB[0]). Once this is done, the resulting 8-by-8 array of bits contains in its rows the correct data bytes read from the sensors. I used to perform this operation on the PIC controller, using left shifts and so on, but that slowed down the system quite a lot. Thus, this operation is now performed on the computer where we process the data, using the following code:

BitArray ba = new BitArray(rxData);
BitArray ba2 = new BitArray(ba.Count);
for (int i = 0; i < ba.Count; i++)
{
    ba2[i] = ba[(((int)(i / 64)) + 1) * 64 - 1 - (i % 8) * 8 - (int)(i / 8) + ((int)(i / 64)) * 8];
}
byte[] data = new byte[rxData.Length];
ba2.CopyTo(data, 0);

请注意,此代码有效.

rxData是接收的字节数组.

我在循环代码中为ba[]的索引使用的公式用于上述数组的镜像.在其他地方检查数组的大小,以确保它始终包含正确的数字(4096)个字节.

The formula I use for the index of ba[] in the loop codes for the mirroring of the arrays I described above. The size of the array is checked elsewhere to make sure it always contains the correct number (4096) of bytes.

到目前为止,这是我遇到问题的背景.

So far this was the background for my problem.

在系统的每个处理循环中,我需要执行两次镜像,因为我的数据处理是基于连续获取的两个阵列之间的差异.速度对我的系统很重要(可能是处理的主要限制),而镜像占到我的处理执行时间的10%到30%.

In each processing loop of my system I need to perform that mirroring twice, because my data processing is on the difference between two arrays acquired consecutively. Speed is important for my system (possibly the main constraint on the processing), and the mirroring accounts for between 10% and 30% of the execution time of my processing.

我想知道是否可以将其他解决方案与镜像代码进行比较,从而可以提高性能.我发现使用BitArrays寻址接收到的字节中不同位的唯一方法.

I would like to know if there are alternative solutions I might compare to my mirroring code and that might allow me to improve performances. Using the BitArrays is the only way I found to address the different bits in the received bytes.

推荐答案

显而易见的解决方案是提取位并再次组合它们.您可以循环执行此操作,但是由于它同时使用了左移和右移,否则您需要负的移入量,因此我将其展开以便于理解和提高速度

The obvious solution is just extracting the bits and combining them again. You can do it with a loop but since it uses both left and right shift at the same time, otherwise you need a negative shift amount, so I unrolled it for easier understanding and more speed

out[0] = ((rxData[0] & 0x80)     )  | ((rxData[1] & 0x80) >> 1) | ((rxData[2] & 0x80) >> 2) | ((rxData[3] & 0x80) >> 3) |
         ((rxData[4] & 0x80) >> 4)  | ((rxData[5] & 0x80) >> 5) | ((rxData[6] & 0x80) >> 6) | ((rxData[7] & 0x80) >> 7);

out[1] = ((rxData[0] & 0x40) << 1)  | ((rxData[1] & 0x40)     ) | ((rxData[2] & 0x40) >> 1) | ((rxData[3] & 0x40) >> 2) |
         ((rxData[4] & 0x40) >> 3)  | ((rxData[5] & 0x40) >> 4) | ((rxData[6] & 0x40) >> 5) | ((rxData[7] & 0x40) >> 6);

out[2] = ((rxData[0] & 0x20) << 2)  | ((rxData[1] & 0x20) << 1) | ((rxData[2] & 0x20)     ) | ((rxData[3] & 0x20) >> 1) |
         ((rxData[4] & 0x20) >> 2)  | ((rxData[5] & 0x20) >> 3) | ((rxData[6] & 0x20) >> 4) | ((rxData[7] & 0x20) >> 5);

out[3] = ((rxData[0] & 0x10) << 3)  | ((rxData[1] & 0x10) << 2) | ((rxData[2] & 0x10) << 1) | ((rxData[3] & 0x10)     ) |
         ((rxData[4] & 0x10) >> 1)  | ((rxData[5] & 0x10) >> 2) | ((rxData[6] & 0x10) >> 3) | ((rxData[7] & 0x10) >> 4);

out[4] = ((rxData[0] & 0x08) << 4)  | ((rxData[1] & 0x08) << 3) | ((rxData[2] & 0x08) << 2) | ((rxData[3] & 0x08) << 1) |
         ((rxData[4] & 0x08)    )   | ((rxData[5] & 0x08) >> 1) | ((rxData[6] & 0x08) >> 2) | ((rxData[7] & 0x08) >> 3);

out[5] = ((rxData[0] & 0x04) << 5)  | ((rxData[1] & 0x04) << 4) | ((rxData[2] & 0x04) << 3) | ((rxData[3] & 0x04) << 2) |
         ((rxData[4] & 0x04) << 1)  | ((rxData[5] & 0x04)     ) | ((rxData[6] & 0x04) >> 1) | ((rxData[7] & 0x04) >> 2);

out[6] = ((rxData[0] & 0x02) << 6)  | ((rxData[1] & 0x02) << 5) | ((rxData[2] & 0x02) << 4) | ((rxData[3] & 0x02) << 3) |
         ((rxData[4] & 0x02) << 2)  | ((rxData[5] & 0x02) << 1) | ((rxData[6] & 0x02)     ) | ((rxData[7] & 0x02) >> 1);

out[7] = ((rxData[0] & 0x01) << 7)  | ((rxData[1] & 0x01) << 6) | ((rxData[2] & 0x01) << 5) | ((rxData[3] & 0x01) << 4) |
         ((rxData[4] & 0x01) << 3)  | ((rxData[5] & 0x01) << 2) | ((rxData[6] & 0x01) << 1) | ((rxData[7] & 0x01)     );

这篇关于围绕对角线镜像位矩阵的性能改进的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆