我有四个uint16,分别命名为a、B、c、d,现在我想这样交换它们:
void swap4(uint16_t &a, uint16_t &b, uint16_t &c, uint16_t &d) { uint16_t temp = a; a = b; b = c; c = d; d = temp; }
我能做些什么来加快这个过程吗?
4dbbbstv1#
在C++中,这是
void swap4(uint16_t &a, uint16_t &b, uint16_t &c, uint16_t &d) { std::tie(a, b, c, d) = std::make_tuple(b, c, d, a); }
kxkpmulp2#
那么,代码应该按照最佳的汇编指令序列编译,假设最低的优化级别。也就是说,如果允许别名,否则请查看273k,它在写入所有值之前加载所有值。但是它太短了,而且有太多的间接性,所以无论如何这不是所有优化潜力所在。内联和优化产生的更大的块有更大的影响。而且,它将允许编译器查看是否发生别名。好消息是,如果你允许编译器,它会完成这一点,这要归功于lto、整体程序优化等(因此取决于正确调用编译器),或者定义与调用在同一个TU中(这可能会调用将其作为头中的内联函数,或将其标记为静态)。
dfddblmv3#
如前所述,首先要确保这确实是一个瓶颈:大多数编译器都应该为此生成高效的代码(除非参数之间可能存在别名)。如果这些16位值是连续存储在内存中的(例如,这是一个四元素向量),那么(a)确保它们在右边界对齐!(b)你可以使用CPU的shuffle指令,这是一个优化,你的编译器可能会也可能不会自己识别。在你进一步操作之前,检查你的编译器的汇编输出;带有-O2的现代GCC实际上会自动识别这种简化(https://godbolt.org/z/qo1jxnbds)。如果你真的想手动滚动,GCC为此提供了一个可移植的__builtin_shuffle宏;对于您用例,您可以编写
typedef uint16_t quadword __attribute__ ((vector_size (8))); quadword input = {a, b, c, d}; const quadword rotate_mask = {1, 2, 3, 0}; quadword output = __builtin_shuffle (input, rotate_mask);
(You我可能不想写得这么精确,而是想将数据重新转换为这些四字类型的数组---请参见上面的编译器资源管理器链接查看示例。)对于x86,此宏生成的底层指令是pshufb/pshufw,(如果您不在GCC上,或者不希望具有可移植性)您可以使用_mm_shuffle_pi16内在指令(https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=shuffle&techs=MMX,SSE&IG_expand=6426)访问该指令。每个现代RISC架构都提供类似的功能。
3条答案
按热度按时间4dbbbstv1#
在C++中,这是
kxkpmulp2#
那么,代码应该按照最佳的汇编指令序列编译,假设最低的优化级别。也就是说,如果允许别名,否则请查看273k,它在写入所有值之前加载所有值。
但是它太短了,而且有太多的间接性,所以无论如何这不是所有优化潜力所在。
内联和优化产生的更大的块有更大的影响。而且,它将允许编译器查看是否发生别名。
好消息是,如果你允许编译器,它会完成这一点,这要归功于lto、整体程序优化等(因此取决于正确调用编译器),或者定义与调用在同一个TU中(这可能会调用将其作为头中的内联函数,或将其标记为静态)。
dfddblmv3#
如前所述,首先要确保这确实是一个瓶颈:大多数编译器都应该为此生成高效的代码(除非参数之间可能存在别名)。
如果这些16位值是连续存储在内存中的(例如,这是一个四元素向量),那么(a)确保它们在右边界对齐!(b)你可以使用CPU的shuffle指令,这是一个优化,你的编译器可能会也可能不会自己识别。在你进一步操作之前,检查你的编译器的汇编输出;带有-O2的现代GCC实际上会自动识别这种简化(https://godbolt.org/z/qo1jxnbds)。
如果你真的想手动滚动,GCC为此提供了一个可移植的__builtin_shuffle宏;对于您用例,您可以编写
(You我可能不想写得这么精确,而是想将数据重新转换为这些四字类型的数组---请参见上面的编译器资源管理器链接查看示例。)
对于x86,此宏生成的底层指令是pshufb/pshufw,(如果您不在GCC上,或者不希望具有可移植性)您可以使用_mm_shuffle_pi16内在指令(https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=shuffle&techs=MMX,SSE&IG_expand=6426)访问该指令。每个现代RISC架构都提供类似的功能。