gri*_*fin 3 c x86 sse simd avx
websocket规范将取消屏蔽数据定义为
j = i MOD 4
transformed-octet-i = original-octet-i XOR masking-key-octet-j
Run Code Online (Sandbox Code Playgroud)
其中mask是4个字节长,每个字节必须应用unmasking.
有没有办法更有效地做到这一点,而不仅仅是循环字节?
运行代码的服务器可以假定为Haswell CPU,OS是内核> 3.2的Linux,因此SSE等都存在.编码是在C语言中完成的,但如果需要,我也可以执行asm.
我试图自己查找解决方案,但是无法弄清楚是否有任何SSE1-5/AVE /中的任何一个都有适当的指令(无论多少延伸 - 多年来失去了多少轨道)
非常感谢你!
编辑:重新阅读规范几次后,似乎它实际上只是用掩码字节对数据字节进行异或,我可以一次做8个字节,直到最后几个字节.问题仍然存在,因为我认为可能还有一种方法可以使用SSE等来优化它(可能一次只处理16个字节?让进程执行for循环?...)
是的,您可以使用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
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
734 次 |
| 最近记录: |