Websocket 数据取消屏蔽/多字节异或

Posted

技术标签:

【中文标题】Websocket 数据取消屏蔽/多字节异或【英文标题】:Websocket data unmasking / multi byte xor 【发布时间】:2013-07-19 09:34:08 【问题描述】:

websocket 规范将取消屏蔽数据定义为

j                   = i MOD 4
transformed-octet-i = original-octet-i XOR masking-key-octet-j

其中掩码为 4 个字节长,并且必须对每个字节应用取消掩码。

有没有比循环字节更有效的方法?

可以假设运行代码的服务器是 Haswell CPU,操作系统是内核 > 3.2 的 Linux,因此 SSE 等都存在。编码是用 C 完成的,但如果需要,我也可以做 asm。

我曾尝试自己查找解决方案,但无法确定是否在数十个 SSE1-5/AVE/ 中的任何一个中都存在适当的指令(无论扩展名 - 多年来都失去了踪迹)

非常感谢!

编辑:在重新阅读规范几次之后,它似乎实际上只是对数据字节与掩码字节进行异或运算,我可以一次执行 8 个字节,直到最后几个字节。问题仍然悬而未决,因为我认为可能仍有一种方法可以使用 SSE 或类似方法来优化它(可能一次处理甚至 16 个字节?让进程执行 for 循环?...)

【问题讨论】:

【参考方案1】:

是的,您可以使用 SSE2 在一条指令中异或 16 个字节,或者使用 AVX2(Haswell 及更高版本)一次异或 32 个字节。

SSE2:

#include <emmintrin.h>                     // SSE2 instrinsics

__m128i v, v_mask;
uint8_t *buff;                             // buffer - must be 16 byte aligned

for (int i = 0; i < N; i += 16)            // note that N must be multiple of 16

    v = _mm_load_si128(&buff[i]);          // load 16 bytes
    v = _mm_xor_si128(v, v_mask);          // XOR with mask
    v = _mm_store_si128(&buff[i], v);      // store 16 masked bytes

AVX2:

#include <immintrin.h>                     // AVX2 intrinsics

__m256i w, w_mask;
uint8_t *buff;                             // buffer - must be 16 byte aligned,
                                           // and preferably 32 byte aligned

for (int i = 0; i < N; i += 32)            // note that N must be multiple of 32

    w = _mm256_load_si256(&buff[i]);       // load 32 bytes
    w = _mm256_xor_si256(w, w_mask);       // XOR with mask
    w = _mm256_store_si256(&buff[i], w);   // store 32 masked bytes

【讨论】:

非常感谢!一旦我测试它工作,我会接受这个作为答案! 目前正试图将其放入我在谷歌上发现的代码中,使用的指针应始终与处理大小对齐 - 这意味着在 AVX2 的情况下它应该是 32 字节对齐 - 如果我没记错的话在那里,你可能想在你的代码 cmets 中更正它! @griffin:使用 AVX/AVX2 稍微复杂一些 - SSE 绝对需要 16 字节对齐,而 AVX/AVX2 可以使用 16 字节对齐(即使对于 32 字节加载/存储),但可能在某些情况下使用 32 字节对齐提供更好的性能。我已经更新了评论。 最好还是只使用序言/尾声,避免在处理不佳的处理器上使用未对齐的负载来轰炸性能。但是,如果您有 AVX,我想所有处理器都支持快速未对齐负载......(至少我遇到过的那些)。

以上是关于Websocket 数据取消屏蔽/多字节异或的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Web 套接字中取消屏蔽多个帧

如何在 netty4 中设置 Web 套接字客户端未屏蔽模式文本框

html5消息推送功能怎么做

PHP Websocket 服务器 - 在 socket_recv 中处理更多帧

websocket 浏览器端 一次 最多可以接受多少字节不报错

Python中的WebSocket帧解码