- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
通过 dpps
计算两个向量的点积是否更快?指令形成SSE 4.1指令集或通过使用一系列addps
, shufps
和mulps
来自上交所1?
最佳答案
答案可能与上下文密切相关,并且完全取决于它在更大的代码流中的使用位置和方式,以及您所使用的硬件。
从历史上看,当英特尔推出新指令时,他们并没有专门为其投入太多硬件区域。如果它得到足够的采用和使用,他们会在后代中投入更多的硬件。因此,就原始 ALU 性能而言,与 SSE2 方式相比,Penryn 上的 _mm_dp_ps
并没有特别令人印象深刻。另一方面,它确实需要较少的指令缓存中的指令,因此当更紧凑的编码性能更好时,它可能会有所帮助。
_mm_dp_ps
的真正问题是作为 SSE 4.1 的一部分,你不能指望它会在每台现代 PC 上得到支持(Valve 的 Steam 硬件调查显示,对于游戏玩家来说,它的支持率约为 85%) 。因此,您最终不得不编写 protected 代码路径而不是直线代码,而这通常花费的成本超过了使用指令所获得的好处。
如果您正在为保证支持它的 CPU 制作二进制文件,那么它很有用。例如,如果您使用 /arch:AVX
(甚至 /arch:AVX2
)进行构建,要么是因为您的目标是 Xbox One 等固定平台,要么是正在构建多个您的 EXE/DLL 版本,您可以假设 SSE 4.1 也将受到支持。
这实际上就是DirectXMath是:
inline XMVECTOR XMVector4Dot( FXMVECTOR V1, FXMVECTOR V2 )
{
#if defined(_XM_NO_INTRINSICS_)
XMVECTOR Result;
Result.vector4_f32[0] =
Result.vector4_f32[1] =
Result.vector4_f32[2] =
Result.vector4_f32[3] = V1.vector4_f32[0] * V2.vector4_f32[0] + V1.vector4_f32[1] * V2.vector4_f32[1] + V1.vector4_f32[2] * V2.vector4_f32[2] + V1.vector4_f32[3] * V2.vector4_f32[3];
return Result;
#elif defined(_M_ARM) || defined(_M_ARM64)
float32x4_t vTemp = vmulq_f32( V1, V2 );
float32x2_t v1 = vget_low_f32( vTemp );
float32x2_t v2 = vget_high_f32( vTemp );
v1 = vpadd_f32( v1, v1 );
v2 = vpadd_f32( v2, v2 );
v1 = vadd_f32( v1, v2 );
return vcombine_f32( v1, v1 );
#elif defined(__AVX__) || defined(__AVX2__)
return _mm_dp_ps( V1, V2, 0xff );
#elif defined(_M_IX86) || defined(_M_X64)
XMVECTOR vTemp2 = V2;
XMVECTOR vTemp = _mm_mul_ps(V1,vTemp2);
vTemp2 = _mm_shuffle_ps(vTemp2,vTemp,_MM_SHUFFLE(1,0,0,0));
vTemp2 = _mm_add_ps(vTemp2,vTemp);
vTemp = _mm_shuffle_ps(vTemp,vTemp2,_MM_SHUFFLE(0,3,0,0));
vTemp = _mm_add_ps(vTemp,vTemp2);
return _mm_shuffle_ps(vTemp,vTemp,_MM_SHUFFLE(2,2,2,2));
#else
#error Unsupported platform
#endif
}
This of course assumes you are going to use the 'scalar' result of a dot-product in additional vector operations. By convention, DirectXMath returns such scalars 'splatted' across the return vector.
参见DirectXMath: SSE4.1 and SSE4.2
更新:虽然不如 SSE/SSE2 支持那么普遍,但对于不使用 /arch:AVX
或 构建的情况,您可能需要 SSE3 支持>/arch:AVX2
并尝试:
inline XMVECTOR XMVector4Dot(FXMVECTOR V1, FXMVECTOR V2)
{
XMVECTOR vTemp = _mm_mul_ps(V1,V2);
vTemp = _mm_hadd_ps( vTemp, vTemp );
return _mm_hadd_ps( vTemp, vTemp );
}
也就是说,目前尚不清楚 hadd
在大多数情况下至少在点积方面优于 SSE/SSE2 add 和 shuffle 解决方案。
关于performance - 点乘积性能与 SSE 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37879678/
在浏览可用的内在函数时,我注意到没有地方可以看到水平的addsub / subadd指令可用。在过时的3DNow中可用!扩展名,但是出于明显的原因,它的使用是不实际的。是什么原因导致SSE3扩展中无法
我需要在 SSE2 汇编程序中编写一些东西。 我所看到的都是内在因素。 我一直在寻找从内在函数到汇编器的转换表,但一直没有找到。 因为我不想玩猜谜游戏,有人可以给我一个链接,将这些可怕的内在函数转换为
我正在研究 SSE 并且是这里的新手。我正在尝试使用 shuffle 指令来随机播放一个 16 位向量,如下所示: 输入: 1 2 3 4 5 6 7 8 输出: 1 5 2 6 3 7 4 8 如何
我有一个用例,其中 x86 CPU 必须将 64 字节的数据写入内存已 mmapp 到用户空间的 PCIe 从属设备。截至目前,我使用 memcpy 来执行此操作,但事实证明它非常慢。我们可以使用像
我最近偶然发现了隐式 SSE/AVX 加载/存储。我认为这些是 GCC 的一些特殊扩展,但后来意识到它们也适用于 MSVC。 __m128 a = *(__m128*)data // same
仅将较高或较低 64 位从整数 SSE 寄存器移动到另一个的最快方法是什么?使用 SSE 4.1,可以使用单个 pblendw 来完成。指令(_mm_blend_epi16)。但是旧的 SSE 版本呢
SSE/AVX 寄存器可以被视为整数或浮点 BigNum。也就是说,人们可能会忽略车道的存在。是否存在一种简单的方法来利用这个观点并将这些寄存器单独或组合用作 BigNum?我问这个问题是因为从我对
我正在尝试比较 SSE float[4] 添加与标准 float[4] 添加。作为演示,我在使用和不使用 SSE 的情况下计算求和分量的总和: #include #include struct P
我处于以下情况: 我正在为不允许 SSE 指令的内核编写代码 我需要做浮点运算 我正在为 x86_64 平台编译 这是一个说明问题的代码示例: int main(int argc, char** ar
我处于以下情况: 我正在为不允许 SSE 指令的内核编写代码 我需要做浮点运算 我正在为 x86_64 平台编译 这是一个说明问题的代码示例: int main(int argc, char** ar
我正在尝试将用 SSE3 内在函数编写的代码转换为 NEON SIMD,但由于 shuffle 函数而卡住了。我查看了 GCC Intrinsic , ARM manuals和其他论坛,但一直无法找到
我正在尝试对一些代码进行 super 优化,我想加快速度的地方如下。 我想取一个 _m128 的点积运算 (_mm_dp_ps) 的答案,并将答案直接保存到寄存器中。但是,使用 _mm_store,这
我正在寻找 SSE 和 AVX 的 SIMD 数学库(最好是开源的)。我的意思是,例如,如果我有一个带有 8 个浮点值的 AVX 寄存器 v,我希望 sin(v) 一次返回所有八个值的 sin。 AM
假设我在 128 位变量/寄存器中有 16 个 ascii 字符(因此有 16 个 8 位数字)。我想创建一个位掩码,其中那些位将是高位,其位位置(索引)由这 16 个字符表示。 例如,如果由这 16
目前我正在使用 Visual C++ 内联汇编使用 SSE 嵌入一些核心功能;但是我意识到 x64 模式不支持内联汇编。 在 x64 架构中构建软件时如何使用 SSE? 最佳答案 在 C/C++ 中使
我正在寻找计算以下函数的有效方法: 输入:__m128i数据,uint8_t in; 输出: bool 值,指示 data 中的任何字节是否在 in 中。 我实际上是在使用它们为容量为 8 的字节实现
我正在寻找计算以下函数的有效方法: 输入:__m128i数据,uint8_t in; 输出: bool 值,指示 data 中的任何字节是否在 in 中。 我实际上是在使用它们为容量为 8 的字节实现
我正在尝试将最新消息拉入顶部页面。目前,每次收到新消息时,最新消息都会显示在下方。 if(typeof(EventSource)!=="undefined") { var source=new Ev
基本上我想做的是获取一个 __m128i 寄存器并将每个负字节的值设置为 -128 (0x80) 并且不更改任何正值。 确切的是: signed char __m128_as_char_arr[16]
有 2 个指针指向要加载到 xmm 寄存器中的 2 个未对齐的 8 字节 block 。如果可能,使用内在函数。如果可能的话,不使用辅助寄存器。没有pinsrd。 (SSSE核心2) 最佳答案 来自
我是一名优秀的程序员,十分优秀!