SSE、SSE2、SSE3指令集的区别?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSE、SSE2、SSE3指令集的区别?相关的知识,希望对你有一定的参考价值。
AMD处理器支持的这些指令集。说说区别。
SSE指令集 SSE(Streaming SIMD Extensions,单指令多数据流扩展)指令集是Intel在Pentium III处理器中率先推出的。其实,早在PIII正式推出之前,Intel公司就曾经通过各种渠道公布过所谓的KNI(Katmai New Instruction)指令集,这个指令集也就是SSE指令集的前身,并一度被很多传媒称之为MMX指令集的下一个版本,即MMX2指令集。究其背景,原来"KNI"指令集是Intel公司最早为其下一代芯片命名的指令集名称,而所谓的"MMX2"则完全是硬件评论家们和媒体凭感觉和印象对"KNI"的 评价,Intel公司从未正式发布过关于MMX2的消息。 而最终推出的SSE指令集也就是所谓胜出的"互联网SSE"指令集。SSE指令集包括了70条指令,其中包含提高3D图形运算效率的50条SIMD(单指令多数据技术)浮点运算指令、12条MMX 整数运算增强指令、8条优化内存中连续数据块传输指令。理论上这些指令对目前流行的图像处理、浮点运算、3D运算、视频处理、音频处理等诸多多媒体应用起到全面强化的作用。S SE指令与3DNow!指令彼此互不兼容,但SSE包含了3DNow!技术的绝大部分功能,只是实现的方法不同。SSE兼容MMX指令,它可以通过SIMD和单时钟周期并行处理多个浮点数据来有效地提高浮点运算速度。SSE2指令集 SSE2(Streaming SIMD Extensions 2,Intel官方称为SIMD 流技术扩展 2或数据流单指令多数据扩展指令集 2)指令集是Intel公司在SSE指令集的基础上发展起来的。相比于SSE,SSE2使用了144个新增指令,扩展了MMX技术和SSE技术,这些指令提高了广大应用程序的运行性能。随MMX技术引进的SIMD整数指令从64位扩展到了128 位,使SIMD整数类型操作的有效执行率成倍提高。双倍精度浮点SIMD指令允许以 SIMD格式同时执行两个浮点操作,提供双倍精度操作支持有助于加速内容创建、财务、工程和科学应用。除SSE2指令之外,最初的SSE指令也得到增强,通过支持多种数据类型(例如,双字和四字)的算术运算,支持灵活并且动态范围更广的计算功能。SSE2指令可让软件开发员极其灵活的实施算法,并在运行诸如MPEG-2、MP3、3D图形等之类的软件时增强性能。Intel是从Willamette核心的Pentium 4开始支持SSE2指令集的,而AMD则是从K8架构的SledgeHammer核心的Opteron开始才支持SSE2指令集的。
SSE3指令集 SSE3(Streaming SIMD Extensions 3,Intel官方称为SIMD 流技术扩展 3或数据流单指令多数据扩展指令集 3)指令集是Intel公司在SSE2指令集的基础上发展起来的。相比于SSE2,SSE3在SSE2的基础上又增加了13个额外的SIMD指令。SSE3 中13个新指令的主要目的是改进线程同步和特定应用程序领域,例如媒体和游戏。这些新增指令强化了处理器在浮点转换至整数、复杂算法、视频编码、SIMD浮点寄存器操作以及线程同步等五个方面的表现,最终达到提升多媒体和游戏性能的目的。Intel是从Prescott核心的Pentium 4开始支持SSE3指令集的,而AMD则是从2005年下半年Troy核心的Opteron开始才支持SSE3的。但是需要注意的是,AMD所支持的SSE3与Intel的SSE3并不完全相同,主要是删除了针对Intel超线程技术优化的部分指令。 3D Now !指令集 由AMD公司提出的3DNo。 参考技术A SSE: SSE是指令集的简称,它包括70条指令,其中包含单指令多数据浮点计算、以及额外的SIMD整数和高速缓存控制指令。其优势包括:更高分辨率的图像浏览和处理、高质量音频、MPEG2视频、同时MPEG2加解密;语音识别占用更少CPU资源;更高精度和更快响应速度。 SSE2:相比于SSE,SSE2使用了144个新增指令,扩展了MMX技术和SSE技术,这些指令提高了广大应用程序的运行性能。随MMX技术引进的SIMD整数指令从64位扩展到了128 位,使SIMD整数类型操作的有效执行率成倍提高。双倍精度浮点SIMD指令允许以 SIMD格式同时执行两个浮点操作,提供双倍精度操作支持有助于加速内容创建、财务、工程和科学应用。 SSE3:相比于SSE2,SSE3在SSE2的基础上又增加了13个额外的SIMD指令。SSE3 中13个新指令的主要目的是改进线程同步和特定应用程序领域,例如媒体和游戏。这些新增指令强化了处理器在浮点转换至整数、复杂算法、视频编码、SIMD浮点寄存器操作以及线程同步等五个方面的表现,最终达到提升多媒体和游戏性能的目的。 参考技术B 一个比一个高级……只能这么说……就像数学公式的解法,一个比一个高效
在 SSE 中使用位集的实现和性能
【中文标题】在 SSE 中使用位集的实现和性能【英文标题】:Implementation and performance of using bitsets with SSE 【发布时间】:2012-05-29 15:28:07 【问题描述】:我正在尝试使用 SSE(在 Visual Studio 上)加快我的方法。我是该地区的新手。我在我的方法中使用的主要数据类型是大小为 32 的位集,我主要使用的逻辑运算是 AND 运算(很少使用 _BitScanForward)。我想知道是否可以使用 SSE 指令来加快我的程序。
这就是我现在正在做的事情(我已经完全完成了,无法直接比较结果):
我使用 _mm_set_ps 加载操作数(位集)。我在位集上使用 to_ulong() 将它们转换为无符号长整数:
__m128 v1 = _mm_set_ps(b1.to_ulong(),b2.to_ulong(),b3.to_ulong(),b4.to_ulong());
__m128 v2 = _mm_set1_ps(b.to_ulong())
接下来是实际的AND运算:
__m128 v3 = _mm_and_ps(v1,v2);
此时,我有两个问题:
我这样做的方式(使用 to_ulong() 将位集转换为无符号长整数)是一种好方法吗?我怀疑有很大的开销可能会扼杀我使用 SSE 可能获得的潜在性能改进。
将 v3 以 4 个位集的形式存储回内存的最佳方法是什么?我打算使用 _mm_storeu_ps 内在函数。
【问题讨论】:
【参考方案1】:有几点:
如果您的位集基本上是 32 位整数,那么您应该使用合适的整数 SIMD 类型,即__m128i
,而不是浮点 (__m128
)
_mm_set_XXX
宏相对昂贵 - 与常规 SSE 内在函数不同,它们可以生成相当多的指令 - 如果您所做的只是一个 AND 操作,那么 _mm_and_XXX 操作带来的任何性能优势都将被_mm_set_XXX
操作的成本
理想情况下,如果您只想对数组中的一组位集进行 AND 运算,那么代码应如下所示:
const int N = 1024;
int32_t b1[N]; // 2 x arrays of input bit sets
int32_t b2[N];
int32_t b3[N]; // 1 x array of output bit sets
for (int i = 0; i < N; i += 4)
__m128i v1 = _mm_loadu_si128(&b1[i]); // load input bits sets
__m128i v2 = _mm_loadu_si128(&b2[i]);
__m128i v3 = _mm_and_si128(v1, v2); // do the bitwise AND
_mm_storeu_si128(&b3[i], v3); // store the result
如果您只想用固定掩码对数组进行原位与操作,那么它会简化为:
const int N = 1024;
int32_t b1[N]; // input/output array of bit sets
const __m128i v2 = _mm_set1_epi32(0x12345678); // mask
for (int i = 0; i < N; i += 4)
__m128i v1 = _mm_loadu_si128(&b1[i]); // load input bits sets
__m128i v3 = _mm_and_si128(v1, v2); // do the bitwise AND
_mm_storeu_si128(&b1[i], v3); // store the result
注意:为了获得更好的性能,请确保您的输入/输出数组是 16 字节对齐的,然后使用 _mm_load_si128
/_mm_store_si128
而不是上面未对齐的对应物。
【讨论】:
Paul,_mm_set1_epi32 不适用于 bitset 实例。是否有适用于实际 bitset 实例的替代方法? 我不是 C++ 专家,但我希望您可以很容易地将 bitset 转换为 32 位 int,无论是使用现有方法还是编写辅助函数。 您可能不是 C++ 专家,但您对我的 SSE 问题帮助很大!我只是不想使用转换/转换来避免开销。祝先生玩得开心! 如果你只用_mm_set1_epi32
设置一个掩码值在主循环之外那么效率不是太重要 - 如果你需要这样做在循环内部,那么您可能需要更仔细地查看如何实现 bitset 和 int 之间的转换。我主要使用 C 来编写高性能 SIMD 代码以避免此类问题。
使用 C 与 C++ 相比有何优势?以上是关于SSE、SSE2、SSE3指令集的区别?的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 中检测 SSE/SSE2 指令集的可用性