gpt4 book ai didi

c - uint32_t * uint32_t = uint64_t vector 与 gcc 相乘

转载 作者:行者123 更新时间:2023-12-04 10:46:20 24 4
gpt4 key购买 nike

我正在尝试将 uint32_t 的 vector 相乘在 uint64_t 中产生完整的 64 位结果gcc 中的 vector 。我期望的结果是 gcc 发出单个 VPMULUDQ操作说明。但是 gcc 输出的代码是可怕的个人 uint32_t源 vector ,然后是完整的 64*64=64 乘法。这是我尝试过的:

#include <stdint.h>

typedef uint32_t v8lu __attribute__ ((vector_size (32)));
typedef uint64_t v4llu __attribute__ ((vector_size (32)));

v4llu mul(v8lu x, v8lu y) {
x[1] = 0; x[3] = 0; x[5] = 0; x[7] = 0;
y[1] = 0; y[3] = 0; y[5] = 0; y[7] = 0;
return (v4llu)x * (v4llu)y;
}

第一个掩盖了 uint32_t 中不需要的部分vector 希望 gcc 能够优化掉 64*64=64 乘法中不需要的部分,然后看到掩码也毫无意义。没有这样的运气。
v4llu mul2(v8lu x, v8lu y) {
v4llu tx = {x[0], x[2], x[4], x[6]};
v4llu ty = {y[0], y[2], y[4], y[6]};
return tx * ty;
}

在这里我尝试创建一个 uint64_t vector 从头开始,只有使用过的零件集。再次 gcc 应该看到每个 uint64_t 的前 32 位是 0 并且不进行完整的 64*64=64 乘法。取而代之的是,发生了大量的值提取和放回操作,并且乘以 64*64=64。
v4llu mul3(v8lu x, v8lu y) {
v4llu t = {x[0] * (uint64_t)y[0], x[2] * (uint64_t)y[2], x[4] * (uint64_t)y[4], x[6] * (uint64_t)y[6]};
return t;
}

让我们通过将部分相乘来构建结果 vector 。也许 gcc 看到它可以使用 VPMULUDQ实现这一目标。没有运气,它回落到 4 IMUL操作码。

有没有办法告诉gcc我想要它做什么(32 * 32 = 64乘以完美放置的所有东西)?

注意:内联汇编或内在不是答案。手动编写操作码显然有效。但随后我将不得不为许多目标架构和功能集编写不同版本的代码。我希望 gcc 能够理解问题并从单个源代码中生成正确的解决方案。

最佳答案

正如 chtz 的评论中所指出的,mul1 和 mul2 都是由 clang 优化的。类似于 mul3 但使用 for 循环的代码也将被优化(但不是很好)。

所以对我来说,表达代码应该做什么的语法似乎是正确的,而 gcc 到目前为止只是缺乏智能来正确优化它。

关于c - uint32_t * uint32_t = uint64_t vector 与 gcc 相乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58837873/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com