Websocket数据取消屏蔽/多字节xor

时间:2013-07-19 09:34:08

标签: c x86 sse simd avx

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

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

其中mask的长度为4个字节,每个字节必须应用unmasking。

有没有办法更有效地做到这一点,而不仅仅是循环字节?

运行代码的服务器可以假定为Haswell CPU,OS是带内核的Linux> 3.2,所以SSE等都存在。编码是在C中完成的,但如果有必要,我也可以做asm。

我试图自己查找解决方案,但是无法弄清楚SSE1-5 / AVE /中的任何一个是否有适当的指令(无论多少扩展 - 多年来失去了许多)

非常感谢!

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

1 个答案:

答案 0 :(得分:6)

是的,您可以使用SSE2在一条指令中XOR 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
}