在我的代码中,我必须处理websocket数据包的"取消屏蔽",这实际上意味着对任意长度的未对齐数据进行异或.感谢SO(Websocket数据取消屏蔽/多字节xor)我已经发现如何(希望)使用SSE2/AVX2扩展加速这一点,但现在看一下,在我看来,我对未对齐数据的处理完全是sub -最佳.有没有办法优化我的代码或者至少使它具有相同的性能更简单,或者我的代码是否已经表现最佳?
这是代码的重要部分(对于这个问题,我假设数据总是至少足以运行一次AVX2循环,但同时它最多只能运行几次):
// circular shift left for uint32
int cshiftl_u32(uint32_t num, uint8_t shift) {
return (num << shift) | (num >> (32 - shift));
}
// circular shift right for uint32
int cshiftr_u32(uint32_t num, uint8_t shift) {
return (num >> shift) | (num << (32 - shift));
}
void optimized_xor_32( uint32_t mask, uint8_t *ds, uint8_t *de ) {
if (ds == de) return; // zero data len -> nothing to do
uint8_t maskOffset = 0;
// process …Run Code Online (Sandbox Code Playgroud) 这个问题更多是出于好奇而不是必要:
是否有可能以if ( !boolvar ) { ...某种方式重写 c 代码,以便将其编译为 1 个 cpu 指令?
我试过在理论层面上思考这个问题,这就是我想出的:
if ( !boolvar ) { ...
需要首先否定变量,然后根据该 -> 2 条指令进行分支(否定 + 分支)
if ( boolvar == false ) { ...
需要将 false 的值加载到寄存器中,然后根据该值进行分支 -> 2 条指令(加载 + 分支)
if ( boolvar != true ) { ...
需要将 true 的值加载到寄存器中,然后根据 -> 2 条指令进行分支(“branch-if-not-equal”)(加载 +“branch-if-not-equal”)
我的假设错了吗?有什么我忽略的吗?
我知道我可以生成程序的中间 asm 版本,但我不知道如何以某种方式使用它,因此我可以一方面打开编译器优化,同时没有if优化掉一个空语句(或者有if 语句与其内容一起优化,给出一些非通用的答案)
PS:当然,我也为此搜索了 google 和 SO,但是搜索词如此短,我真的找不到任何有用的东西
PPS:我可以使用语义等效的版本,该版本不是语法等效的,例如不使用if.
编辑:如果我对发出的 asm 指令的假设是错误的,请随时纠正我。
Edit2:我实际上在大约 15 年前学习了 asm,并在大约 …
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循环?...)