3

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 循环?...)

4

1 回答 1

7

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

上交所2:

#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
}
于 2013-07-19T10:20:51.257 回答