- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
到目前为止,我设法发现:
在 Windows 上使用 SSE3、SSSE3、SSE4.1、SSE 4.2、AVX2 和 AVX-512 有什么注意事项吗?
一些说明:如果我使用来自 SSE/AVX 集之一的指令,我需要这个来确定我的程序将在哪些操作系统上运行。
最佳答案
引入新架构状态的扩展需要特殊的操作系统支持,因为操作系统必须在上下文切换时保存/恢复恢复更多数据。因此,从操作系统的角度来看,如果操作系统支持 SSE,则无需执行任何额外操作即可让用户空间代码运行 SSSE3 指令。
SSE、AVX 和 AVX512 是引入新架构状态的扩展。
xmm
regs(和 MXCSR
用于舍入模式和 FP 异常状态)ymm
(下半部分是旧的 xmm
regs)。zmm
(扩展 x/ymm
regs),并且还在 64 位模式下将向量 regs 的数量加倍:zmm0-zmm31。 x/y/zmm16..31 只能通过矢量指令的 AVX-512 编码(EVEX 前缀)访问,因此有趣的是可以在没有 requiring vzeroupper
的情况下使用, 和 aren't affected by it .k0..k7
64 位掩码寄存器(或 Xeon Phi 中没有 AVX-512BW 的 16 位)在 AVX-512 中也是新的。您可以使用 CPUID 指令以通常的方式检查 CPU 是否支持 SSE 或 AVX。
在不保存/恢复上下文切换的新架构状态的多任务操作系统上使用新扩展时,为了防止静默数据损坏,如果操作系统没有,SSE 指令将作为非法指令出错 set an OS-support bit in a control register .因此,矢量扩展在不知道如何保存/恢复该扩展的必要状态的操作系统上“不起作用”。
对于 SSE,可能没有任何干净的独立于操作系统的方法来检测操作系统是否已 promise 通过设置 CR4.OSFXSR
在上下文切换时保存/恢复 SSE 状态, CR4.OSXMMEXCPT
等位,因为even reading a control register is privileged ,并且没有反射(reflect)该设置的 CPUID 位。 SSE 支持如此广泛,以至于您必须使用非常古老的版本(或自制软件)操作系统才能解决这个问题。
对于 AVX,我们不需要操作系统支持来检测 AVX 是否可用(由硬件支持并由操作系统启用):用户空间可以运行 xgetbv
并检查启用功能标志以查看操作系统是否已启用 AVX 指令以无故障运行。
来自 Intel's intro to AVX :
- Verify that the operating system supports XGETBV using
CPUID.1:ECX.OSXSAVE bit 27 = 1
.- At the same time, verify that
CPUID.1:ECX bit 28=1
(Intel AVX supported) and/or bit 25=1 (AESsupported) ... (and other bits for FMA, AES, and PCLMULQDQ)- Issue
XGETBV
, and verify that the feature-enabled maskat bits 1 and 2 are11b
(XMM state and YMM state enabled by theoperating system).
调用操作系统提供的函数来检测操作系统支持可能更容易,而不是使用内联汇编或功能检测库来完成所有这些工作。比如Win7SP1引入了GetEnabledXStateFeatures
以及对 AVX CPU 的支持。 (不太可能或不可能找到在没有 SSE 的 CPU 上运行的 Win7SP1,因此对于 SSE,您只需检查 CPUID 和操作系统版本即可。)
这也被理解为操作系统的上下文切换将正确保存/恢复完整状态的 promise ,当然,有缺陷的、恶意的或深奥的操作系统(可能是协作式多任务处理?)可能会有所不同。对于包括 Windows 在内的主流操作系统,这确实意味着 YMM 寄存器将像您期望的那样保持其值。
AVX512 也是如此:您可以检查指令集的 CPUID 功能位,并检查操作系统是否已 promise 管理新架构状态通过在 XSETBV 中启用正确的位来进行上下文切换。 (所以你应该检查 XGETBV)。检查 XGETBV 结果和 0xE6 等于 0xE6。
关于windows - 哪些版本的 Windows 支持/需要哪些 CPU 多媒体扩展? (如何检查 SSE 或 AVX 是否完全可用?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34069054/
我正在尝试优化一些矩阵计算,我想知道是否可以在编译时检测 SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI[ 1] 是否由编译器启用?非常适合 GCC 和 Clan
我想仅使用avx而不是avx2来实现64位转置操作。它应该这样做: // in = Hh Hl Lh Ll // | X | // out = Hh Lh Hl Ll 这就是使
如果我有一个 AVX 寄存器,里面有 4 个 double 值,我想将它的反向存储在另一个寄存器中,是否可以用一个内部命令来实现? 例如:如果我在 SSE 寄存器中有 4 个 float ,我可以使用
最初我试图重现 Agner Fog 的微体系结构指南部分“YMM 和 ZMM 向量指令的预热期”中描述的效果,它说: The processor turns off the upper parts o
我的 C++ 代码使用 SSE,现在我想改进它以支持 AVX(当它可用时)。因此,我检测 AVX 何时可用并调用使用 AVX 命令的函数。我使用 Win7 SP1 + VS2010 SP1 和带有 A
我有一大块内存,比如说 256 KiB 或更长。我想计算整个 block 中 1 位的数量,或者换句话说:将所有字节的“总体计数”值相加。 我知道 AVX-512 有一个 VPOPCNTDQ inst
有多快 tensorflow-gpu与没有 AVX 和 AVX2 相比,有 AVX 和 AVX2 吗? 我试图使用谷歌找到答案,但没有成功。很难重新编译tensorflow-gpu对于 Windows
为什么avx sqrt(非压缩)指令有三个操作数? vsqrtsd xmm1, xmm2, xmm3 这是否意味着类似于 xmm1=xmm2=sqrt(xmm3)? 编辑:下面的详细答案但总之流水线的
我正在研究Intel intrinsics guide的展开和压缩操作。我对这两个概念感到困惑: 对于__m128d _mm_mask_expand_pd (__m128d src, __mmask8
我在 Intel Intrinsic Guide v2.7 中找不到它们。您知道 AVX 或 AVX2 指令集是否支持它们吗? 最佳答案 原始 AVX 指令集中没有分散或收集指令。 AVX2 添加了收
我正在尝试将函数转换为 AVX 版本。函数本身基本上只是比较浮点数并返回真/假取决于计算。 这是原始函数: bool testSingle(float* thisFloat, float* other
我遇到了 AVX 内部指令 _mm256_testc_pd() 的一个非常奇怪的行为。在这里你可以看到这个功能的描述 https://software.intel.com/sites/landingp
我有一个 256 位 AVX 寄存器,其中包含 4 个单精度复数,存储为实数、虚数、实数、虚数等。我目前正在将整个 256 位寄存器写回内存并在那里求和,但这似乎效率低下. 如何使用 AVX(或 AV
#include "stdio.h" #include "math.h" #include "stdlib.h" #include "x86intrin.h" void dd_m(double *cl
有没有办法对 AVX 寄存器进行水平异或——特别是对 256 位寄存器的四个 64 位组件进行异或? 目标是获得 AVX 寄存器的所有 4 个 64 位组件的异或。它本质上与水平添加( _mm256_
当我尝试使用 AVX 获取数据时,出现运行时错误 - 段错误: int i = 0; const int sz = 9; size_t *src1 = (size_t *)_mm_malloc(sz*
当我尝试使用 AVX 展开最简单的循环时,出现运行时错误 - 段错误: const int sz = 9; float *src = (float *)_mm_malloc(sz*
我想将两个 256 位 vector (__m256d) 合并为一个 256位 vector ,通过省略每个 64 位 double 的上半部分。 所以,如果在下面,a_i, b_i, ... 是 3
我测试了以下简单的功能 void mul(double *a, double *b) { for (int i = 0; i #include #include #include #defi
_mm_i32gather_epi32() 的当前英特尔内在函数指南将每个子词的计算地址描述为: addr := base_addr + SignExtend64(vindex[m+31:m]) *
我是一名优秀的程序员,十分优秀!