是否有一个内在函数可以在输入数组中的所有位置设置单个值,其中相应位置在提供的 BitMask 中具有 1 位?
10101010 是位掩码
值为 121
它将设置位置 0,2,4,6 值为 121
我使用以下内容来提取 的符号位__mm128
:
const int sign_mask = _mm_movemask_ps(a);
Run Code Online (Sandbox Code Playgroud)
我现在想使用以下内容来混合两个向量:
v_add = _mm_blendv_ps(a, v_add_neg, _mm_castsi128_ps(v_mask));
Run Code Online (Sandbox Code Playgroud)
v_mask
需要来自sign_mask
但我找不到执行此操作的内在函数。
a
该代码的目的是根据另一个向量的相应元素中的符号来更改向量元素的符号。
当 NEON 向量指令在 ARM 设备上可用时,我一直在寻找复制各种数据量的快速方法。
\n我做了一些基准测试,并得到了一些有趣的结果。我试图理解我所看到的东西。
\n我有四个版本来复制数据:
\n逐个元素复制:
\nfor (int i = 0; i < size; ++i)\n{\n copy[i] = orig[i];\n}\n
Run Code Online (Sandbox Code Playgroud)\n此代码将四个值加载到临时寄存器中,然后将该寄存器复制到输出。
\n因此,负载数量减少了一半。可能有一种方法可以跳过临时寄存器并将负载减少四分之一,但我还没有找到方法。
\nint32x4_t tmp;\nfor (int i = 0; i < size; i += 4)\n{\n tmp = vld1q_s32(orig + i); // load 4 elements to tmp SIMD register\n vst1q_s32(©2[i], tmp); // copy 4 elements from tmp SIMD register\n}\n
Run Code Online (Sandbox Code Playgroud)\nmemcpy
,使用memcpy
,但一次复制 4 …
想象以下代码:
uint64_t x = 0x81C6E3292A71F955ULL;
uint32_t y = (uint32_t) (x >> 32);
Run Code Online (Sandbox Code Playgroud)
y
接收 64 位整数的较高 32 位部分。我的问题是是否存在任何内在函数或任何 CPU 指令可以在不进行移动和移位的情况下在单个操作中执行此操作?
至少铛(在上面挂尝试,它-在线)创建两个指令mov rax, rdi
,并shr rax, 32
对于这一点,所以无论是铛不会做这样的优化,或不存在这样的特殊指令。
如果存在像movhi dst_reg, src_reg
.
我想要一个类似 的函数的实现_mm256_lzcnt_epi8(__m256i a)
,其中对于每个 8 位元素,都会计算和提取尾随零的数量。
在上一个实现对前导零进行计数的问题中,有一个使用查找表的解决方案。我想知道是否可以使用相同的方法来实现这一点。
请仅使用 AVX 和 AVX2,并且输入的行为0
可以是未定义的。
AVX2:AVX 寄存器中 8 位元素上的 BitScanReverse 或 CountLeadingZeros
感谢您的帮助!
我正在学习 SIMD 内在函数和并行计算。我不确定Intel对x86指令的定义sqrtpd
是否 表示将同时计算传递给它的两个数字的平方根:
对源操作数(第二个操作数)中的两个、四个或八个压缩双精度浮点值的平方根执行 SIMD 计算,并将压缩双精度浮点结果存储在目标操作数(第二个操作数)中第一个操作数)。
我知道它明确表示SIMD 计算,但这是否意味着对于此操作,将同时计算两个数字的根?
我有一个 float32 数字向量。对于每个元素,我必须找到 cos,sin
我想使用查找表而不是默认库。是否有 ARM 内部代码可以用于此目的?
我对编译器 intrinsincs 很陌生。我有 4 个 uint64_t 整数存储在 _m256i 中。
__m256i vj = _mm256_setr_epi64x(1, 2, 3, 4);
__m256i one = _mm256_set_epi64x(1, 1, 1, 1);
__m256i vf = _mm256_and_si256(vj, one); // vf = {1, 0, 1, 0}
Run Code Online (Sandbox Code Playgroud)
我想得到一个__m256d res = {1.0, -1.0, 1.0, -1.0}
基于 vf 的值,如下所示:
double value[2] = {-1.0, 1.0};
for(int i = 0; i < 4; i++)
res[i] = value[vf[i]];
Run Code Online (Sandbox Code Playgroud)
从 vf 和 value 生成 res 的最佳方法应该是什么?非常感谢您的帮助。
我一直认为num * 0.5f
和num / 2.0f
是等价的,因为我认为编译器足够聪明,可以优化除法。所以今天我决定测试一下这个理论,但我发现的结果却难住了我。
给出以下示例代码:
float mul(float num) {
return num * 0.5f;
}
float div(float num) {
return num / 2.0f;
}
Run Code Online (Sandbox Code Playgroud)
x86-64 clang 和 gcc 都会生成以下汇编输出:
mul(float):
push rbp
mov rbp, rsp
movss DWORD PTR [rbp-4], xmm0
movss xmm1, DWORD PTR [rbp-4]
movss xmm0, DWORD PTR .LC0[rip]
mulss xmm0, xmm1
pop rbp
ret
div(float):
push rbp
mov rbp, rsp
movss DWORD PTR [rbp-4], xmm0
movss xmm0, DWORD PTR [rbp-4]
movss xmm1, DWORD PTR …
Run Code Online (Sandbox Code Playgroud) intrinsics ×9
simd ×5
c ×4
c++ ×4
avx ×3
arm ×2
avx2 ×2
sse ×2
instructions ×1
intel ×1
neon ×1
performance ×1
x86 ×1