尽可能快地在网络流中搜索块

时间:2017-12-19 02:56:09

标签: c++ performance search stream header

我想问一下在网络流中搜索模式的方法。

我目前的方法是分配一个大缓存,将数据从套接字放入缓存,当数据大小超过阈值时,然后开始在缓存中搜索所有同步头(使用KMP算法)。它有效,但看起来有些麻烦。

标题是非常简单的标志,例如“0xFFEEBBAA1290”。

有没有一个技巧可以实时检查标题,而不会累积?即在接收数据时,检查完整数据块是否及时到达。

数据连续到达,没有任何间隔表示不同的数据blcok。

我使用循环缓冲区来检查第一个标头和下一个标头来决定整个块,但是许多模数(用于循环缓冲区索引)操作会大大降低速度。我只是使用memcmp来查找标题。

仅供参考,我更喜欢的语言是C / C ++。

希望得到你的建议。任何参考链接也欢迎。

谢谢。

请允许我添加有关此问题的一些详细信息。

数据来自不受我控制的电路板。 设备从其来源的任意位置发送数据,并且不遵循任何规则,例如建立连接时必须以封装前面的标头开始。更糟糕的是块长度没有固定,我必须通过检查2个头来阻止。

在我的方法中,我尝试在开始时找到第一个标头,如果不满足,我将丢弃每个字节,直到标头到来。 这样至少我可以保证第一个头是在缓存开始时(缓存大小比KMP方法小得多,因为我不希望延迟搜索头),然后继续接收数据并同时检查下一个头。

如果找到块,则块数据将移动到其他进程,然后第二个头将移动到缓存的前面。 它导致缓存应该重新对齐以接受下一个数据,这就是我使用循环缓冲区(存储数据到数组)来实现的原因。即,只设置读写位置,而不是实际移动缓存中的数据。

由于字节块操作和性能考虑,尝试了

列表或向量但未使用。

问题是我必须在数据到达时继续检查下一个标题

是否有一种优雅的方法可以避免频繁的字节扫描?

或者如果速度合理,我也可以接受频繁的字节扫描,但是用于计算循环缓冲区中读取和写入位置的模运算似乎会降低性能。 我使用了不同的分析工具,并且都表明频繁的模数是性能瓶颈。

1 个答案:

答案 0 :(得分:0)

"尽可能快地实时"已经是一个矛盾了。实时意味着数据到达的速度;没有必要比那更快。实际上,实时通常比批处理慢。

实时还需要可用时间和时间的硬数据,这两者都不可用。

您的标题显示为< 8字节,即1个缓存行。不太可能需要KMP或类似的算法。检查0xFF的高速缓存行中的所有字节几乎肯定比针对0xFF, 0xEE, 0xBB, 0xAA, 0x12 or 0x90检查单个字节更快。

现在,&#34;众多模数(用于循环缓冲区索引)操作大大降低了速度&#34;是一个现实的问题。但这确实有一个简单的解决方案。确保缓冲区大小为编译时常量幂为2 x%(1<<N)等于x & ((1<<N)-1)