前置条件:
我读取256Kbyte块数据,它应该只有两种状态:
但是,某些数据可能会更改为不可预测的值。我需要找到它们。我可以一个字节一个字节地搜索它,但看起来太慢了,所以我决定用二分法来做它 - 看起来像:
如何将代码写入循环?我是否需要17种不同大小的参考静态数据并使用memcmp
?
我目前的代码如下:
unsigned char gReferData1[2] = {0xFF, 0xFF};
unsigned char gReferData2[2] = {0x00, 0x00};
int main(void)
{
int i = 0, result1 = 0, result2 =0;
read_somewhere(readBuff, sizeof(readBuff)); //read out data
//first test first two bytes
result1 = memcmp(gReferData1, readBuff, 2); //test if 0xFFFF
result2 = memcmp(gReferData2, readBuff, 2); //test if 0x0000
if(result1 == 0)
{
// means all rest data should be 0xFF
for(i=2; i<(0x40000/2); i++)
{
result1 = memcmp(gReferData1, readBuff + offet, 2); //test if 0xFFFF
if(result1 != 0)
{
//means find
// do error handle
}
offset+=2;
}
}
else if(result2 == 0)
{
// means all rest data should be 0x00
for(i=2; i<(0x40000/2); i++)
{
result2 = memcmp(gReferData2, readBuff + offet, 2); //test if 0x0000
if(result2 != 0)
{
//means find
// do error handle
}
offset+=2;
}
}
else
{
//just error
// do error handle
}
return 0;
}
答案 0 :(得分:3)
为了在随机位置找到缺陷,您需要至少检查一次每个字节。对于此,没有比O(n)
更快的算法。
但是,您提出的算法需要多次检查每个字节。为了“将读出数据分成相等的一半,然后进行比较”,您必须读取每个字节。这就是memcmp
将在内部执行的操作:从头到尾遍历两个内存段,直到出现异常。这不是魔术。它不能比用简单的循环更有效率地做到这一点。
可能加快速度(测试并测量它!)的优化可能是不是逐字节地遍历数据数组,而是以sizeof(long)
为步长然后在比较之前将该细分投放到long
。这利用了许多32位CPU(不是全部,测试和测量它!)的事实,比较两个32位值并不需要花费更多时间来比较两个8位值。
答案 1 :(得分:2)
您需要检查该缓冲区的无字节是否具有非法状态,因此您必须至少检查一次每个字节。
在大多数系统上,跳转是昂贵的,顺序读取字节比任何东西都便宜。因此,我可以使用更多顺序读取。
您可能尝试做的一件事是按顺序读取整个缓冲区,并将每个条目与前一个条目的条目进行比较,&#34;条目&#34;是一个字节或16,32或64位字,取决于哪个更快:
DATATYPE previous = *bufptr;
for (i = 1; i < (length of buffer divided by DATATYPE size); i++) {
if (previous != *(bufptr++)) {
break;
}
}
if (i != (length of buffer divided by DATATYPE size)) {
// There has been an error.
}
// Verify that previous is either 0 or the appropriate number of 0xF's.
另一种可能性是在缓冲区的前半部分和缓冲区的后半部分之间运行memcmp()
,然后(仅适用于lols)验证第一个字节确实是0x00或0xFF。如果两半中相同相对位置的两个位同时翻转,则会失败。这有多大可能?它还取决于硬件(假设缓冲区是两个完全相同的芯片,由相同的宇宙射线以完全正确的角度进行串联......)。
根据架构,使用的编译器和优化,任一解决方案可能会变得更快;可能不是那么多。