gpt4 book ai didi

c - pinsrd/_mm_insert_epi32 与字节指针对齐?

转载 作者:行者123 更新时间:2023-11-30 16:46:32 35 4
gpt4 key购买 nike

类似于this question ,我想将几​​个 24 位值收集到 SSE/AVX 寄存器的 32 位双字中。进一步:

  • 每个值都位于距基指针不连续的偏移处
  • 每个值的偏移量只有 1 字节对齐
  • 我可以确保读取超出(或之前)每个值的 vector 是安全的

AVX2(高性能?)收集解决方案可以,但我还需要 AVX 之前的支持。看起来带有指示 1 字节对齐的 SIB 字节的pinsrd 正是我想要的,但我不知道如何让编译器发出此指令编码...

使用标准内在函数:

uint32_t *p = &base[offset];
vec = _mm_insert_epi32(vec, *p, 1); // for each dword...

假设偏移量对齐,产生合理的编码:

660f3a2244_b5_0001 pinsrd   $0x1, (%rbp,%rsi,4), %xmm0

但是,我想实际发出:

660f3a2244_35_0001 pinsrd   $0x1, (%rbp,%rsi), %xmm0

并手动预乘偏移 3。

这种编码(通过十六进制编辑链接的二进制文件进行测试)似乎工作得很好。但是……我怎样才能发出它呢?没有大量的类型转换或属性__align__ 似乎有效。显而易见的方法:

uint8_t *p = &base[offset*3];
vec = _mm_insert_epi32(vec, *p, 1);

当然,在插入之前会通过零扩展将一个字节取消引用为双字。

我的内联汇编尝试:

static inline __m128i __attribute__((always_inline))
_mm_insertu_epi32(__m128i a, void *b, long o, const int8_t imm8)
{
__asm__("pinsrd %3, (%1, %2), %0" : "+x"(a) : "r"(b), "r"(o), "i"(imm8));
return a;
}

产量:

660f3a22041601      pinsrd  $0x1, (%rsi,%rdx), %xmm0

这是有希望的,但似乎完全混淆了优化器;所有周围的代码都被扰乱得无法识别。

有没有办法在不使用纯汇编的情况下做到这一点? (我想使用内在...)

另请参阅:Dereference pointers in XMM register

最佳答案

@harold,谢谢。

我已经在执行 movd 和几个pinsrd(例如 clang)。但是我在 godbolt 上看到 clang/gcc/icc 使用各种解包模式,所以我将对它们进行分析。

不幸的是,“避免聚集”并不是解决方案。但你是对的,内在确实可以与任意对齐一起工作。简单的指针转换最终会做正确的事情(即产生可能未对齐的地址):

__m128i gather32_scale4(int *b, long o0, long o1, long o2, long o3)
{
return _mm_set_epi32(b[o0], b[o1], b[o2], b[o3]);
// movd xmm0, dword ptr [rdi + 4*r8]
// pinsrd xmm0, dword ptr [rdi + 4*rcx], 1
// pinsrd xmm0, dword ptr [rdi + 4*rdx], 2
// pinsrd xmm0, dword ptr [rdi + 4*rsi], 3
}

__m128i gather32_scale1(int *b, long o0, long o1, long o2, long o3)
{
return _mm_set_epi32(
*(int *)&((char *)b)[o0],
*(int *)&((char *)b)[o1],
*(int *)&((char *)b)[o2],
*(int *)&((char *)b)[o3]);
// movd xmm0, dword ptr [rdi + r8]
// pinsrd xmm0, dword ptr [rdi + rcx], 1
// pinsrd xmm0, dword ptr [rdi + rdx], 2
// pinsrd xmm0, dword ptr [rdi + rsi], 3
}

(与手动编写的_mm_insert_epi32类似)

关于c - pinsrd/_mm_insert_epi32 与字节指针对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43694221/

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