使用 SSE / AVX 并行化 C 代码
Posted
技术标签:
【中文标题】使用 SSE / AVX 并行化 C 代码【英文标题】:Parallelize C Code using SSE / AVX 【发布时间】:2014-08-04 13:37:39 【问题描述】:我想使用 SSE/AVX 命令并行化我现有的代码。 我完全是这些说明集的菜鸟
代码截图如下
static void inline enc_round(uint32_t b0[4], uint32_t b1[4], const uint32_t **kpp)
for (int n = 0; n<4; n++)
b0[n] = crypto_ft_tab[0][byte(b1[n], 0)] ^
crypto_ft_tab[1][byte(b1[(n + 1) & 3], 1)] ^
crypto_ft_tab[2][byte(b1[(n + 2) & 3], 2)] ^
crypto_ft_tab[3][byte(b1[(n + 3) & 3], 3)] ^ *(*kpp + n);
*kpp += 4;
具有以下类型定义
const uint32_t crypto_ft_tab[4][256]
static inline uint8_t byte(const uint32_t x, const unsigned n)
我想并行化逻辑 ANDS
编辑:对不起,我的意思是按位异或
任何建议什么是最好的启动方式或我应该启动哪些命令?
提前致谢
【问题讨论】:
我没有看到任何逻辑与 - 我看到按位异或 - 这就是你的意思吗? @PaulR 也许他的意思是(n + 1) & 3
部分?
啊 - 按位 ANDs - 也许 - 这个问题需要澄清一下。
@PaulR vOv 是的...您可以编辑(再次 :) )以便问题更清楚(因为显然根本没有合乎逻辑的and
s)。
当然 - 我只编辑了标签 - 我会让 OP 修复内容,因为我只是猜测真正的要求。
【参考方案1】:
在 GCC 和 Visual Studio 中,您可以轻松地使用编译器内部函数来生成 SSE 和 AVX 指令。
可在英特尔网站上找到可用指令列表:https://software.intel.com/sites/landingpage/IntrinsicsGuide/
使用 SSE2,这看起来像这样:
// load values 1 to 4 as 16 byte blocks from the given addresses:
__m128i value1 = _mm_loadu_((__m128i*)address1);
__m128i value2 = _mm_loadu_((__m128i*)address2);
__m128i value3 = _mm_loadu_((__m128i*)address3);
__m128i value4 = _mm_loadu_((__m128i*)address4);
// build xor
__m128i result = _mm_xor_si128(value1, value2);
result = _mm_xor_si128(result, value3);
result = _mm_xor_si128(result, value4);
// store the result somewhere into memory
_mm_storeu_si128((__m128i*)addressForResult);
请注意,每个 __m128i 变量都包含一个完整的 16 字节向量数据。使用 AVX2 内部函数,您甚至可以处理 32 字节块中的数据。
【讨论】:
以上是关于使用 SSE / AVX 并行化 C 代码的主要内容,如果未能解决你的问题,请参考以下文章
使用 SSE 矢量化在 OpenMP 中将内部循环与残差计算并行化