【发布时间】:2021-04-09 19:19:24
【问题描述】:
我正在努力寻找正确的 C++/clang 语句来解决以下问题。首先请注意,由于在算术发生之前整数提升,以下内容不会溢出 unsigned short。
unsigned short testme = 16320;
testme = testme * 257 / 64;
结果是 65535。但是当我使用 simd 在无符号短裤的向量上尝试类似的东西时,它不起作用:
#import <simd/simd.h>
template <typename T>
void muldiv( T* data, unsigned multiply, unsigned divide)
{
*data = (*data * multiply) / divide;
}
...
simd::ushort4 testme = 16320;
muldiv( &testme, 257, 64);
这给出了四个 1023 的向量。没有发生整数提升和乘法包装。在查看了 clang 文档之后,我能想到的最好的就是这个。请注意,调用者必须提供一个虚拟参数,以提供工作精度作为模板类型参数。
#import <simd/simd.h>
template <typename T, typename W>
void muldiv( T* data, unsigned multiply, unsigned divide, W workingtype)
{
*data = __builtin_convertvector( (__builtin_convertvector(*data, W) * multiply) / divide, T);
}
...
simd::ushort4 testme = 16320;
muldiv( &testme, 257, 64, simd::uint4());
现在我得到一个包含四个 65535 的向量。 T 是模板参数的原因是有时我会传递 ushort4、ushort8、ushort16 等。但我发现将工作精度作为参数传递是很难看的,因为它始终是无符号整数。我想不出一种从 T 中提取 simd-length 的方法,因此我可以在本地声明类型 W 。函数中这样的东西会很好:
typedef unsigned int W __attribute__((__vector_size__( ?? )));
但我不知道如何让它发挥作用。我尝试过这样的事情:
bool hopeful = __is_convertible_to( simd::ushort4, simd::uint4);
但希望总是返回 false。
谁能告诉我我需要什么魔法?
注意这是在提供
【问题讨论】:
-
simd 对不同的向量类型没有任何特征吗?如果没有,那么也许你可以自己动手?
-
这是金属
namespace simd吗? -
您是否尝试编写一个匹配
__attribute__((__ext_vector_type__(3)))、__attribute__((__ext_vector_type__(2)))等的特征并将其复制到新类型? -
一个简单的
sizeof? -
请提供minimal reproducible example。你的
simd::uint4是在哪里定义的?另外,我认为通常向上转换不是最有效的解决方案。而不是testme * 257 / 64我会计算(testme << 2) + (testme >> 6)
标签: c++ templates clang simd metal