尽快在网络流中搜索块
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尽快在网络流中搜索块相关的知识,希望对你有一定的参考价值。
我想问一下在网络流中搜索模式的方法。
我目前的方法是分配一个大缓存,将数据从套接字放入缓存,当数据大小超过阈值时,然后开始在缓存中搜索所有同步头(使用KMP算法)。它有效,但看起来有点麻烦。
标头是非常简单的标志,例如“0xFFEEBBAA1290”。
有没有一个技巧可以实时检查标题,而不是累积?即在接收数据时,检查完整数据块是否及时到达。
数据连续到达,没有任何间隔表示不同的数据块。
我使用循环缓冲区来检查第一个标头和下一个标头来决定整个块,但是大量的模数(用于循环缓冲区索引)操作会大大降低速度。我只是使用memcmp来查找标题。
仅供参考,我更喜欢的语言是C / C ++。
希望得到你的建议。任何参考链接也欢迎。
谢谢。
请允许我添加有关此问题的一些详细信息。
数据来自一块不受我控制的电路板。设备从其来源的任意位置发送数据,并且不遵循任何规则,例如建立连接时必须以封装前面的标头开始。更糟糕的是块长度不固定,我必须通过检查2个头来阻止。
在我的方法中,我尝试在开始时找到第一个头,如果它不符合,我将丢弃每个字节,直到头来。这样至少我可以保证第一个头是在缓存开始时(缓存大小比KMP方法小得多,因为我不希望延迟搜索头),然后继续接收数据并同时检查下一个头。
如果找到块,则块数据将移动到其他进程,然后第二个头将移动到缓存的前面。它导致缓存应该重新对齐以接受下一个数据,这就是我使用循环缓冲区(存储数据到数组)来实现的原因。即,只设置读写位置,而不是实际移动缓存中的数据。
由于字节块操作和性能考虑,尝试了列表或向量但未使用。
问题是我必须在数据到达时不断检查下一个标题。
是否有一种优雅的方法来避免这种频繁的字节扫描?
或者如果速度合理,我也可以接受频繁的字节扫描,但是用于计算循环缓冲区中读取和写入位置的模运算似乎会降低性能。我使用了不同的分析工具,并且都表明频繁的模数是性能瓶颈。
“尽可能快地实时”已经是一个矛盾。实时意味着数据到达的速度;没有必要比那更快。实际上,实时通常比批处理慢。
实时还需要可用的时间和时间的硬数据,这两者都不可用。
您的标头显示为<8个字节,即1个缓存行。不太可能需要KMP或类似的算法。检查缓存行中0xFF
的所有字节几乎肯定比检查0xFF, 0xEE, 0xBB, 0xAA, 0x12 or 0x90
的单个字节要快。
现在,“众多模数(用于循环缓冲区索引)操作大大降低了速度”是一个现实问题。但这确实有一个简单的解决方案。确保缓冲区大小是编译时常量,并且是2的幂。 x%(1<<N)
等于x & ((1<<N)-1)
以上是关于尽快在网络流中搜索块的主要内容,如果未能解决你的问题,请参考以下文章
Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题
Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题