- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我没有想到特定的用例;我在问这是否真的是英特尔内在函数的设计缺陷/限制,或者我是否只是遗漏了一些东西。
如果您想将标量浮点数与现有 vector 相结合,似乎没有办法在没有高元素归零或使用 Intel 内在函数将标量广播到 vector 的情况下做到这一点。我还没有研究过 GNU C 原生 vector 扩展和相关的内置函数。
如果额外的内在优化消失,这不会太糟糕,但它不会与 gcc(5.4 或 6.2)。也没有很好的使用方法 pmovzx
或 insertps
作为负载,由于相关原因,它们的内在函数仅采用 vector 参数。 (并且 gcc 不会将标量-> vector 加载折叠到 asm 指令中。)
__m128 replace_lower_two_elements(__m128 v, float x) {
__m128 xv = _mm_set_ss(x); // WANTED: something else for this step, some compilers actually compile this to a separate insn
return _mm_shuffle_ps(v, xv, 0); // lower 2 elements are both x, and the garbage is gone
}
gcc 5.3 -march=nehalem -O3 输出,以启用 SSE4.1 并针对该英特尔 CPU 进行调整:(没有 SSE4.1 更糟;多个指令将上层元素归零)。
insertps xmm1, xmm1, 0xe # pointless zeroing of upper elements. shufps only reads the low element of xmm1
shufps xmm0, xmm1, 0 # The function *should* just compile to this.
ret
TL:DR:这个问题的其余部分只是问你是否真的可以有效地做到这一点,如果不能,为什么不能。
_mm_set_ss(x)
)或将标量复制到它们(
_mm_set1_ps(x)
)上的指令。与其编写编译器必须优化的东西,不如首先用 C 语言“有效地”编写它?即使是最近的 gcc 也没有优化它,所以这是一个真正的(但次要的)问题。
__m256 _mm256_castps128_ps256 (__m128 a)
,这将是可能的。 .即产生一个
__m128
上元素中有未定义的垃圾,下元素中有浮点数,如果标量浮点数/ double 数已经在 xmm 寄存器中,则编译为零 asm 指令。
_mm256_castps128_ps256
如上所述。标量已注册情况的最通用解决方案。__m128 _mm_move_ss_scalar (__m128 a, float s)
: 替换 vector 的低元素 a
带标量 s
.如果有通用标量->__m128(上一个要点),这实际上不是必需的。 ( movss
的 reg-reg 形式合并,不像加载形式归零,也不像 movd
在这两种情况下都归零上元素。要复制一个寄存器保存一个没有错误依赖的标量浮点数,使用 movaps
)。__m128i _mm_loadzxbd (const uint8_t *four_bytes)
和其他尺寸的 PMOVZX/PMOVSX:AFAICT, there's no good safe way to use the PMOVZX intrinsics as a load ,因为不方便的安全方式不会用 gcc 优化掉。__m128 _mm_insertload_ps (__m128 a, float *s, const int imm8)
. INSERTPS与加载的行为不同:忽略 imm8 的高 2 位,并且它始终采用有效地址处的标量(而不是内存中 vector 的元素)。这使它可以处理非 16B 对齐的地址,并且即使在 float
出现错误的情况下也能正常工作。就在未映射的页面之前。_mm_load_ss()
到 INSERTPS 的内存操作数中。 (请注意,如果 imm8 的高 2 位不都为零,则 _mm_insert_ps(xmm0, _mm_load_ss(), imm8)
可以编译为 insertps xmm0,xmm0,foo
,使用不同的 imm8 将 vec 中的元素归零,就像 src 元素实际上是由 MOVSS 生成的零一样从内存中。在这种情况下,Clang 实际上使用 XORPS/BLENDPS)__m128 float_to_vec(float a){ something(a); }
.
_mm256_castps128_ps256
的同时添加一个带有未定义上层元素的 float->__m128 .
这是编译器内部问题使其难以实现吗? 也许特别是ICC内部结构?
__vectorcall
)上的主要调用约定采用 xmm0 中的第一个 FP arg 并返回 xmm0 中的标量 FP args,上层元素未定义。 (有关 ABI 文档,请参阅
x86 标签维基)。这意味着编译器在具有未知上层元素的寄存器中具有标量浮点数/ double 数的情况并不少见。这在矢量化内循环中很少见,所以我认为避免这些无用的指令只会节省一些代码大小。
最佳答案
它在 GNU C 内联汇编中是可行的,但是这很丑陋并且无法进行许多优化,包括常量传播( https://gcc.gnu.org/wiki/DontUseInlineAsm )。 这不是公认的答案 .我将此添加为答案而不是问题的一部分,因此问题不会很大。
// don't use this: defeating optimizations is probably worse than an extra instruction
#ifdef __GNUC__
__m128 float_to_vec_inlineasm(float x) {
__m128 retval;
asm ("" : "=x"(retval) : "0"(x)); // matching constraint: provide x in the same xmm reg as retval
return retval;
}
#endif
ret
,根据需要,并将内联让您
shufps
将标量转换为 vector :
gcc5.3
float_to_vec_and_shuffle_asm(float __vector(4), float):
shufps xmm0, xmm1, 0 # tmp93, xv,
ret
__m128 float_to_vec(float a){ something(a); }
编译成一个
ret
操作说明。对
double
的尝试使用
_mm_undefined_pd()
和
_mm_move_sd()
实际上使用 gcc 使代码更糟(请参阅上面的 Godbolt 链接)。
the existing float->__m128 intrinsics 都没有帮助。
__m128 float_to_vec(float x){ return _mm_set_ss(x); }
编译为:
# gcc5.3 -march=core2
movd eax, xmm0 # movd xmm0,xmm0 would work; IDK why gcc doesn't do that
movd xmm0, eax
ret
# gcc5.3 -march=nehalem
insertps xmm0, xmm0, 0xe
ret
# clang3.8 -march=nehalem
xorps xmm1, xmm1
blendps xmm0, xmm1, 14 # xmm0 = xmm0[0],xmm1[1,2,3]
ret
关于c - 如何将标量合并为 vector 而不编译器浪费指令将上元素归零?英特尔内在函数的设计限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39318496/
我尝试设置一个文件来使用 PyCharm 编写 AI。 我正在使用的教程:https://www.youtube.com/watch?v=ujTCoH21GlA 当我运行代码时: $ import t
我一直在寻找很长一段时间,似乎无法找到一个官方/结论性的数字来引用英特尔至强四核可以完成的单精度浮点运算/时钟周期的数量。我有一个 Intel Xeon 四核 E5530 CPU。 我希望用它来计算我
在深度学习与神经网络领域,研究人员通常离不开 GPU。得益于 GPU 极高内存带宽和较多核心数,研究人员可以更快地获得模型训练的结果。与此同时,CPU 受限于自身较少的核心数,计算运行需要较长的时间
我试图了解 TCS 启用的 SGX 线程与 SDK 提供的不受信任线程之间的区别. 如果我理解正确的话,TCS 允许多个逻辑处理器进入同一个飞地。每个逻辑处理器都有自己的 TCS,因此也有自己的入口点
我想通过 IACA 分析器运行一些代码以查看它使用了多少个 uops——我从一个简单的函数开始,看看它是否在工作。 不幸的是,当我插入 IACA 说要使用的宏时,生成的程序集非常不同,因此对它的任何分
是否有可能获得许可的开发人员证书,以在生产模式下签署经过安全审查、社区开发的开源 SGX 软件二进制文件,并将其发布在 apt 或 rpm 等开源存储库中? 我刚问过英特尔 SGX 团队,他们说只有经
我正在尝试模拟 Intel 8080 指令集,但我被这条指令卡住了 OUT D8 ,根据书Intel 8080/8085 Assembly Language Programming它说 OUT ins
我在使用一些现有的 FORTRAN 代码时发现了一个问题。尽管它已经预料到需要在重新分配之前释放数组,但这从来没有必要。我现在需要它来执行此操作,但它无法正常运行。 当前的伪代码大约是: MODULE
我正在尝试在内存中对齐以下类型的数据: type foo real, allocatable, dimension(:) :: bar1, bar2 !dir$ attributes al
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
似乎获得和释放语义的公认定义是这样的: (引自 http://msdn.microsoft.com/en-us/library/windows/hardware/ff540496(v=vs.85).a
这是我对英特尔 TBB 流图性能进行基准测试的尝试。这是设置: 一个广播节点发送continue_msg到 N 后继节点 (一broadcast_node) 每个后继节点执行一次计算,该计算需要 t
我有两个问题 第一个问题:我使用 css3、HTML5、JavaScript 开发应用程序。在我的应用程序中,我需要从数据库中获取数据。我该怎么做? 第二个问题:intel xdk 在构建 l 时必须
在英特尔手册的第 3 卷中,它包含硬件事件计数器的描述: BACLEAR_FORCE_IQ Counts number of times a BACLEAR was forced by the Ins
嘿,我正在使用 Intel xdk 开发混合应用程序。我已经创建了注册表,然后我将代码放在那里。我尝试使用 Php Mysql 将数据库插入我的数据库后。 如果我单击注册按钮,它会显示这样的错误 [
我想知道是否可以让英特尔 C++ 编译器(或其他编译器,如 gcc 或 clang)显示一些来自优化器的消息。我想知道优化器究竟对我的代码做了什么。默认情况下,编译器只打印非常基本的东西,比如未使用的
我正在使用 64 位架构的 Intel 程序集优化我的视频解码器。为了优化,我使用 AVX2 指令集。 我的开发环境:- 操作系统:- Win 7(64位) IDE:- MSVS 2008(教授) C
如果这是一个非常愚蠢的问题,我很抱歉;我的 Fortran 不太好。我正在移植一些旧的 Fortran 代码,并遇到了这个子例程定义: SUBROUTINE SET_HYDROMODULE(HYDRO
请问,我是否可以将 Intel XDK API 和 Phonegap API 集成到单个移动应用程序中?这是因为,某些 API 仅在 Phonegap 中可用,反之亦然。 最佳答案 是的,如果我正确理
在 x86 中查找任意操作码的含义(例如 0xC8 )的相对快速简便的方法是什么? Intel Software Developer's manual搜索起来不是很有趣...... 最佳答案 查询 t
我是一名优秀的程序员,十分优秀!