标签: simd

memcpy 击败 SIMD 内在函数

当 NEON 向量指令在 ARM 设备上可用时,我一直在寻找复制各种数据量的快速方法。

\n

我做了一些基准测试,并得到了一些有趣的结果。我试图理解我所看到的东西。

\n

我有四个版本来复制数据:

\n

1. 基线

\n

逐个元素复制:

\n
for (int i = 0; i < size; ++i)\n{\n    copy[i] = orig[i];\n}\n
Run Code Online (Sandbox Code Playgroud)\n

2. 霓虹灯

\n

此代码将四个值加载到临时寄存器中,然后将该寄存器复制到输出。

\n

因此,负载数量减少了一半。可能有一种方法可以跳过临时寄存器并将负载减少四分之一,但我还没有找到方法。

\n
int32x4_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(&copy2[i], tmp); // copy 4 elements from tmp SIMD register\n}\n
Run Code Online (Sandbox Code Playgroud)\n

3. 阶梯式memcpy,

\n

使用memcpy,但一次复制 4 …

c++ performance arm simd intrinsics

0
推荐指数
1
解决办法
1717
查看次数

AVX2:AVX 寄存器中 8 位元素的 CountTrailingZeros

我想要一个类似 的函数的实现_mm256_lzcnt_epi8(__m256i a),其中对于每个 8 位元素,都会计算和提取尾随零的数量。

在上一个实现对前导零进行计数的问题中,有一个使用查找表的解决方案。我想知道是否可以使用相同的方法来实现这一点。

请仅使用 AVX 和 AVX2,并且输入的行为0可以是未定义的。

AVX2:AVX 寄存器中 8 位元素上的 BitScanReverse 或 CountLeadingZeros

感谢您的帮助!

c++ simd intrinsics avx avx2

0
推荐指数
1
解决办法
363
查看次数

sqrtpd指令是否同时计算sqrt?

我正在学习 SIMD 内在函数和并行计算。我不确定Intel对x86指令的定义sqrtpd是否 表示将同时计算传递给它的两个数字的平方根:


对源操作数(第二个操作数)中的两个、四个或八个压缩双精度浮点值的平方根执行 SIMD 计算,并将压缩双精度浮点结果存储在目标操作数(第二个操作数)中第一个操作数)。


我知道它明确表示SIMD 计算,但这是否意味着对于此操作,将同时计算两个数字的根?

parallel-processing sse simd cpu-architecture intrinsics

0
推荐指数
1
解决办法
388
查看次数

并行嵌套循环中的数据竞争

我有一个三重嵌套循环,我想并行化,但是,我遇到了数据争用问题。我很确定我需要以某种方式使用缩减,但我不太知道如何使用。

这是有问题的循环:

#pragma omp parallel for simd collapse(3)
    for (uint64 u = 0; u < nu; ++u) {
        for (uint64 e = 0; e < ne; ++e) {
            for (uint64 v = 0; v < nv; ++v) {
                uAT[u][e] += _uT[u][e][v] * wA[e][v];
            }
        }
    }

Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下,为什么这会导致数据竞争?我真的很想了解这一点,这样我将来就不会遇到这些问题。另外,这个循环可以并行吗?如果是这样,怎么办?

编辑:我怎么知道存在数据竞争?

这个循环应该完成的任务(并且它是串行完成的)是计算不连续伽辽金框架中函数的元素平均值。当我多次运行代码时,有时会得到不同的结果,尽管它应该总是产生相同的结果。产生的错误值总是小于应有的值,这就是为什么我假设某些值没有被添加。也许这张图可以更好地解释它:第三个单元格中的平均值显然是错误的(太小)。 第三个单元格中的平均值显然是错误的(太小)。

c simd openmp data-race

0
推荐指数
1
解决办法
239
查看次数

如何根据 _m256i 元素的偶数或奇数有条件地创建 -1.0 和 +1.0 的 _m256d?

我对编译器 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 的最佳方法应该是什么?非常感谢您的帮助。

simd intrinsics avx avx2

0
推荐指数
1
解决办法
66
查看次数

如何计算 __m128 变量。(另外 _mm_blendv_ps 是做什么的)?

所以我阅读了英特尔关于 _mm_blendv_ps 的文档,但不太明白该函数的真正作用。所以我写了下面的代码:

    __m128 a = { 18.0,4.0,19.0,21.0 };
    __m128 b = { 67.0,92.0,888.0,47.0 };
    __m128 mask = { 1.0,0.0,0.0,1.0 };

    __m128 result = _mm_blendv_ps(a, b, mask);
    cout << "Result is: " << result[0] << " " << result[1] << " " << result[2] << " " << result[4] << endl;
Run Code Online (Sandbox Code Playgroud)

但我收到错误“没有运算符 [] 与这些操作数匹配”。为什么我无法访问结果?结果不是32位浮点向量吗?

那么为什么我无法访问结果呢?我怎样才能访问它?cout 的结果是什么(blendv 做什么)?

c++ sse simd

0
推荐指数
1
解决办法
359
查看次数

如何从lsb的__m64值创建一个8位掩码?

我有一个用例,其中我有位数组,每个位表示为8位整数,例如uint8_t data[] = {0,1,0,1,0,1,0,1};我想通过仅提取每个值的lsb来创建一个整数.我知道使用int _mm_movemask_pi8 (__m64 a)函数我可以创建一个掩码但这个内在函数只需要一个字节的msb而不是lsb.是否有类似的内在或有效方法来提取lsb以创建单个8位整数?

c++ simd avx mmx avx2

-1
推荐指数
1
解决办法
164
查看次数

为什么C / RUST中的一个加法计算在结果ASM中有3个双精度浮点加法工具?

简单的C代码,只需添加一个双精度。

void test(double *a, double *b, long n) {
    for (long j = 0; j < n; j++)
    for (long i = 0; i < n; i++) {
        b[i] = b[i] + a[j];
    }
}
Run Code Online (Sandbox Code Playgroud)

在编译器资源管理器中获取ASM结果:https : //godbolt.org/z/tJ-d39

有一addpd和二addsd。两者都是与双精度有关的。

另一个类似的锈代码,获得了更多的双精度添加工具:https//godbolt.org/z/c49Wuh

pub unsafe fn test(a: &mut [f64], b: &mut [f64], n: usize) {
    for j in 0..n {
        for i in 0..n {
            *b.get_unchecked_mut(i) = *b.get_unchecked_mut(i) + *a.get_unchecked_mut(j);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c assembly simd rust auto-vectorization

-1
推荐指数
2
解决办法
113
查看次数

SIMD (avx) 处理如何工作?例如,如果我想要 10 个 32 位浮点数,如何放入 256 位 avx 向量?

我正在学习 C avx 内在函数,我想知道它是如何工作的。

我很熟悉我可以做这样的事情:

__m256 evens = _mm256_set_ps(2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0);
Run Code Online (Sandbox Code Playgroud)

这里我存储 8 个 32 位浮点数。所以这是 256 位。

但是假设我正在编写一个线性代数库。然后我如何处理任意数量的向量;例如,如何将 10 个 32 位浮点数放入 avx 向量中?

如果您能提供一些例子,我将非常感激

c simd avx

-1
推荐指数
1
解决办法
161
查看次数

Cortex-a8上的NEON有多少个功能单元?

我的问题是ARM cortex-a8上的NEON单元有多少功能单元?如果我已经正确读取,TRM没有明确说明ARM cortex-a8的NEON核心上的功能单元数量.

embedded arm simd neon cortex-a8

-2
推荐指数
1
解决办法
395
查看次数