- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近一直在使用 SSE 内部 int _mm_extract_epi8 (__m128i src, const int ndx)
,根据引用“从索引选择的压缩整数数组元素中提取整数字节” .这正是我想要的。
但是,我通过 _m128i
上的 _mm_cmpestri
确定索引,它执行具有显式长度的字符串数据的压缩比较并生成索引。该索引的范围是 0..16,其中 0..15 表示有效索引,16 表示未找到索引。现在要提取索引位置的整数,我想到了执行以下操作:
const int index = _mm_cmpestri(...);
if (index >= 0 && index < 16) {
int intAtIndex = _mm_extract_epi8(..., index);
}
这给我们留下了 gcc (-O0) 编译器错误:
错误:选择器必须是 0..15 范围内的整数常量
解决此问题的一个糟糕方法是在索引上设置一个开关
,并为 0..15 范围内的每个索引调用一个 _mm_extract_epi8
。我的问题是是否有我没有看到的更好/更好的方法。
更新:用-O3优化,没有编译错误;不过仍然使用 -O0。
最佳答案
只是总结并结束问题。
我们讨论了从 _m128i sse
中提取 [0..15] 中索引 i 处的字节的 3 个选项,其中 i 不能在编译时减少为文字:
1) 开关 & _mm_extract_epi8
:在 i 上有一个 开关
并且 [0..15] 中的每个 i 都有一个 case 执行 _mm_extract_epi8(sse ,i)
;像 i 现在一样工作是编译时文字。
2) Union hack: 有一个 union SSE128i { __m128i sse;字符[16]数组; }
,将其初始化为 SSE128i sse = { _mm_loadu_si128(...) }
并使用 sse.array[i]
访问索引 i 处的字节。
3) 将第i个元素打乱到位置0和_mm_extract_epi8
:使用_mm_shuffle_epi8(sse,_mm_set1_epi8(i))
将第i个元素打乱到位置0;使用 _mm_extract_epi8(sse,0)
提取它。
评估:我在 Intel Sandy Bridge 和 AMD Bulldozer 架构上对这三个选项进行了基准测试。转换选项以微弱优势获胜。如果有人感兴趣,我可以发布更详细的数字和基准设置。
更新:评估基准设置:解析 1GB 文件的每个字节。对于某些特殊字节,增加一个计数器。使用_mm_cmpistri
查找特殊字节的索引;然后使用提到的三种方法之一“提取”字节,并区分大小写,其中计数器递增。代码是使用 GCC 4.6 和 -std=c++0x -O3 -march=native
编译的。
对于每种方法,基准测试在 Sandy Bridge 机器上运行 25 次。结果(以秒为单位的运行时间的平均值和标准偏差):
切换和提取:平均值:1071.45标准差:2.72006
联盟黑客:平均值:1078.61标准偏差:2.87131
从位置 0 开始混洗和提取:平均值:1079.32标准偏差:2.69808
差异很小。我还没有机会查看生成的 asm。不过,看到差异可能会很有趣。现在我无法发布基准测试的完整代码,因为它包含非公开来源。如果我有时间,我会提取这些并发布源代码。
关于c++ - _mm_extract_epi8(...) intrinsic 以非文字整数作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12913451/
在 Intel Intrinsics Guide 中,在几个 Intrinsics 的底部有“延迟和吞吐量信息”,列出了几个 CPUID 的性能。 例如,Intrinsics Guide 中的表格对于
Intel Intrinsics Guide表示内在 _mm256_rsqrt_ps 的相对误差至多为 1.5*2^-12。但是,当我将 _mm256_rsqrt_ps 的结果与平方根倒数的标准 C+
我正在尝试使用内在函数编写 AVX2 代码。想知道如何使用 Intel 内在函数将 YMM 中的最低字广播到整个 YMM。我知道用汇编代码我可以写 vpbroadcastw ymm1, xmm0 因为
我在 Intel Intrinsic Guide v2.7 中找不到它们。您知道 AVX 或 AVX2 指令集是否支持它们吗? 最佳答案 原始 AVX 指令集中没有分散或收集指令。 AVX2 添加了收
是否存在强制 C 编译器直接使用内存操作数的语法? 在过去美好的 asm 时代,我们只需在指令中写入操作数的位置 - “真实”寄存器或内存指针(由地址指向的位置)。 但在 C 的内在函数伪汇编中,我看
https://web.archive.org/web/20170227190422/http://hilbert-space.de/?p=22 在这个过时的网站上,它表明手写 asm 会比内在函数带
我使用英特尔内在函数具有以下函数: int c_lattice_worker( int lm, double* inArr, double* outArr, int arrLen,
所以我试图将一个常量与短 int a[101] 与英特尔内在函数相乘。我已经用加法完成了它,但我似乎无法弄清楚为什么它不适用于乘法。另外,在我们使用 32 位整数之前,现在我们使用 16 位短整数,因
我对内在函数、simd 和一般的低级编程真的一窍不通。我正在迈出第一步,但就我所见,我正在使用的所有内部函数(Intel ones 现在)只是 C++ 通用代码,没有任何“特殊”或专用关键字。 这似乎
我一直在试验 SSE 内在函数,我似乎遇到了一个我无法弄清楚的奇怪错误。我正在计算两个 float 组的内积,一次计算 4 个元素。 为了测试,我将两个数组的每个元素都设置为 1,因此乘积应该是 ==
如何正确使用 RenderScript Intrinsics。 如图http://android-developers.blogspot.com/2013/08/renderscript-intrin
我正在尝试优化一些循环并且我已经成功了,但我想知道我是否只做了部分正确的事情。比如说我有这个循环: for(i=0;i int main() { int i{0}; float a[1
我的问题是当头文件包含在 SDK 中(从 VC 10 安装)并且我用来编译驱动程序的 WDK 不了解时,如何在内核空间(在 Windows 上)使用内部函数这个文件。当我 #include 一切正常,
我正在使用 SSE 对图像中的像素执行按位非运算。 我有一些问题: 可以使用 OpenMP 进一步优化吗? 我的算法中是否存在可以优化的瓶颈? 这是我的代码: unsigned int iSSE2Si
我最近一直在使用 SSE 内部 int _mm_extract_epi8 (__m128i src, const int ndx),根据引用“从索引选择的压缩整数数组元素中提取整数字节” .这正是我想
只是想知道#pragma intrinsic(_m_prefetchw) 是什么意思? 最佳答案 据我所知,看起来有人打算修改某些 MSVC++ 特定设置。但是,该设置不是 intrinsic pra
我有以下代码: #include #include #include long long lzcnt(long long l) { return __lzcnt64(l); } int
浏览Kotlin源码时,发现有些地方会抛出NotImplementedError: public suspend inline val coroutineContext: CoroutineConte
我正在尝试通过阅读 Intel Intrinsics Guide 来开始使用 AVX512 内在函数但到目前为止我发现它没有定义命名数据类型或用于解释的伪代码语法。没有这样的定义,所谓的指南对我起码没
java.lang.StackOverflowError at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:164)
我是一名优秀的程序员,十分优秀!