相关疑难解决方法(0)

在大数组中有效地找到最低有效设置位?

我有一个巨大的内存块(位向量),在一个内存页中大小为N位,考虑N平均为 5000,即 5k 位来存储一些标志信息。
在某个时间点(超级频繁 - 关键),我需要在整个大位向量中找到第一个位集。现在我每 64 个字都这样做,即在 ) 的帮助下__builtin_ctzll。但是当N增长并且搜索算法无法改进时,可以通过扩展内存访问宽度来扩展此搜索。这是几句话的主要问题

有一条被调用的汇编指令BSF 给出了最高设置位(GCC's __builtin_ctzll())的位置。因此,在 arch 中,我可以在 64 位字中廉价地找到最高位。

但是通过内存宽度进行缩放呢?
例如,有没有办法用 128 / 256 / 512 位寄存器有效地做到这一点?
基本上我对一些 C API 函数来实现这个感兴趣,但也想知道这个方法是基于什么的。

UPD:至于 CPU,我对这种优化感兴趣,以支持以下 CPU 阵容:
英特尔至强 E3-12XX、英特尔至强 E5-22XX/26XX/E56XX、英特尔酷睿 i3-5XX/4XXX/8XXX、英特尔酷睿 i5- 7XX、英特尔赛扬 G18XX/G49XX(英特尔凌动 N2600、英特尔赛扬 N2807、Cortex-A53/72 可选)

PS在最终位扫描之前提到的算法中,我需要将k(平均 20-40)个N位向量与 CPU AND相加(AND 结果只是位扫描的准备阶段)。这也适用于内存宽度缩放(即比每 64 位字 AND 更有效)

另请阅读:查找第一组

c assembly bit-manipulation x86-64 avx

13
推荐指数
2
解决办法
465
查看次数

使用 simd 在双打数组中找到 nan

这个问题非常类似于:

用于浮点相等比较的 SIMD 指令(使用 NaN == NaN)

尽管该问题侧重于 128 位向量,并且对识别 +0 和 -0 有要求。

我有一种感觉,我自己可能会得到这个,但英特尔内在指南页面似乎已关闭:/

我的目标是获取一个双精度数组并返回数组中是否存在 NaN。我预计大多数情况下不会有一条路线,并希望该路线具有最佳性能。

最初,我打算对自己进行 4 个双打的比较,反映用于 NaN 检测的非 SIMD 方法(即 NaN 只有值为a != atrue 的值)。就像是:

data *double = ...
__m256d a, b;
int temp = 0;

//This bit would be in a loop over the array
//I'd probably put a sentinel in and loop over while !temp
a = _mm256_loadu_pd(data);
b = _mm256_cmp_pd(a, a, _CMP_NEQ_UQ);
temp = temp | _mm256_movemask_pd(b);
Run Code Online (Sandbox Code Playgroud)

但是,在一些比较示例中,除了比较本身之外,似乎还进行了某种 NaN 检测。我简单地想,如果像这样的东西 _CMP_EQ_UQ …

c sse simd nan avx

6
推荐指数
1
解决办法
248
查看次数

计算两个 __m256i 变量的元素之间的逻辑与 (&&) 的最快方法是什么,寻找任何一对非零元素

据我所知,C++中的整数可以像布尔值一样对待,我们可以有这样的代码:

int a = 6, b = 10;
if (a && b) do something ---> true as both a and b are non-zero
Run Code Online (Sandbox Code Playgroud)

现在,假设我们有:

__m256i a, b;
Run Code Online (Sandbox Code Playgroud)

我需要对 __m256i 中的所有 4 个长变量应用逻辑与 (&&),如果一对非零则返回 true。我的意思是:

(a[0] && b[0]) || (a[1] && b[1]) || ...
Run Code Online (Sandbox Code Playgroud)

我们是否有用于此目的的 AVX 或 AVX2 快速代码?

我找不到任何直接的指令用于此目的,并且肯定,使用按位与 (&) 也是不一样的。

c++ simd avx avx2 logical-and

6
推荐指数
1
解决办法
341
查看次数

检查向量是否包含大于零的任何元素

如果有人可以帮助编写一个接收AVX向量的函数并检查它是否包含任何大于零的元素,我将感激不尽.

我编写了以下代码,但它不是最佳的,因为它存储元素然后操纵它.矢量应该作为一个整体进行检查.

int check(__m256 vector)
{
  float * temp;
  posix_memalign ((void **) &temp, 32, 8 * sizeof(float));    
  _mm256_store_ps( temp, vector );

  int flag=0;
  for(int k=0; k<8; k++)
  {
    flag= ( (temp[k]>0) ? 1 : 0 );
    if (flag==1) return 1;
  }

  free( temp);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c vector avx

5
推荐指数
1
解决办法
883
查看次数

_mm_testc_ps 和 _mm_testc_pd 与 _mm_testc_si128

如您所知,前两个是特定于 AVX 的内在函数,第二个是 SSE4.1 内在函数。两组内在函数都可用于检查 2 个浮点向量的相等性。我的具体用例是:

  • _mm_cmpeq_ps_mm_cmpeq_pd,然后是
  • _mm_testc_ps_mm_testc_pd在结果上,使用适当的掩码

但是 AVX 为“传统”内在函数提供了等价物,因此_mm_testc_si128在将结果转换为__m128i. 我的问题是,这两个用例中的哪一个会导致更好的性能,以及我在哪里可以找到 AVX 提供了哪些旧的 SSE 指令。

c x86 simd avx sse4

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

标签 统计

avx ×5

c ×4

simd ×3

assembly ×1

avx2 ×1

bit-manipulation ×1

c++ ×1

logical-and ×1

nan ×1

sse ×1

sse4 ×1

vector ×1

x86 ×1

x86-64 ×1