查看“SSE”的源代码
←
SSE
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{Floats}} ''' 流式单指令多数据扩展 (SSE-Streaming SIMD Extensions) ''' == Streaming SIMD Extensions (SSE) == === 简介 === 奔腾III中引入了SSE,并为英特尔指令集额外提供了70条指令。 SSE指令可以帮助增加由于单指令,多数据 (SIMD) 指令的数据。 这些指令可以在多个数据上并行执行公共表达式。 SSE附带8个(64位模式下为16个)XMM寄存器(XMM0-7(15)),它们是128位寄存器。 某些SSE指令 (movntdqa,movdqa,movdqu等...) 可以在单个操作中从内存中加载16个字节或将16个字节存储到内存中。 此外,SSE还引入了一些非时态提示指令(movntdqa和movntdq),允许将一次性内存位置存储在非时态内存中,以便这些位置引用不会污染小型片上缓存。 由于此更改添加了新的寄存器,因此默认禁用,因为当时的典型操作系统还不能将这些寄存器保存在任务交换机上。 为了支持SSE,您需要实现单独的代码路径来保存和恢复SSE状态 (因为这些指令将在不支持它的处理器上导致异常),以及新异常的处理程序。 之后,您可以告诉CPU在userland任务中启用SSE使用。 ===检查SSE=== 要检查SSE CPUID.01h: 需要设置EDX.SSE[bit25] <source lang="asm"> mov eax, 0x1 cpuid test edx, 1<<25 jz .noSSE ;SSE is available </source> ===增加支持=== 为了允许执行SSE指令而不生成#UD,我们需要更改CR0和CR4寄存器。 清除 CR0.EM bit (bit 2) [ CR0 &= ~(1 << 2) ] 设置 CR0.MP bit (bit 1) [ CR0 |= (1 << 1) ] 设置 CR4.OSFXSR bit (bit 9) [ CR4 |= (1 << 9) ] 设定 CR4.OSXMMEXCPT bit (bit 10) [ CR4 |= (1 << 10) ] 这是一个asm示例: <source lang="asm"> ;now enable SSE and the like mov eax, cr0 and ax, 0xFFFB ; 清除协处理器仿真CR0.EM or ax, 0x2 ;设置协处理器监控CR0.MP mov cr0, eax mov eax, cr4 or ax, 3 << 9 ; 同时设置CR4.OSFXSR和CR4.OSXMMEXCPT mov cr4, eax ret </source> === FXSAVE 和 FXRSTOR === FXSAVE和FXRSTOR用于从内存中保存和加载完整的SSE、x87 FPU和MMX状态。 主机需要为存储分配512字节,并将该内存指针用作FXSAVE或FXRSTOR的操作数。 在使用这两条指令之前,请确保检查FXSR位的CPUID功能。 另外,像大多数SSE指令一样,内存操作数需要对齐16字节,否则将发生#GP异常。 记住在*任何MXCSR修改发生之前执行FXSAVE*,否则寄存器很可能会被覆盖或根据未知状态MXCSR_MASK设置为0。 示例用法: <source lang="c"> char fxsave_region[512] __attribute__((aligned(16))); asm volatile(" fxsave %0 "::"m"(fxsave_region)); </source> or in asm: <source lang="asm"> segment .code SaveFloats: fxsave [SavedFloats] segment .data align 16 SavedFloats: TIMES 512 db 0 </source> 陷阱: 仅支持一级保存。 ===MXCSR及其助手LDMXCSR和STMXCSR=== MXCSR寄存器保存用于SSE浮点运算的所有掩码和标志信息。 就像x87 FPU控制字一样,如果您想屏蔽某些异常或想指定舍入类型,则需要修改MXCSR。 位16-31是保留的,如果设置,将导致#GP异常。 LDMXCSR和STMXCSR分别加载和写入MXCSR寄存器。 它们都需要一个32位的内存操作数。 在使用这些指令(CR4.OSFXSR=1、CR0.EM=0和CR0.TS=0)之前,需要已经设置SSE支持。 如果设置了7-12位,则所有SSE浮点异常都将被屏蔽。 位0-5是异常状态标志,在发生相应异常时设置。 位13-14是RC(舍入控制)位。 RC:0 = 取最近,RC:1 = 向下取,RC:2 = 向上取,RC:3 = 截断。 == 更新到SSE == 后来的处理器为要在向量寄存器(vector registers)上执行的不同工作添加了更多指令。 在适当的SSE支持下支持它们不需要操作系统方面的任何努力 (AVX除外,请参见下文)。 然而,指令的实际用户应该检查这些指令是否确实存在。 ===CPUID位=== =====SSE2===== <small>'''Streaming SIMD Extensions 2 (SSE2)'''</small><br /> SSE2的位可以在CPUID page 1的EDX位26中找到。 =====SSE3===== <small>'''Streaming SIMD Extensions 3 (SSE3)'''</small><br /> SSE3的位可以在CPUID page 1的ECX位0中找到。 =====SSSE3===== <small>'''Supplemental Streaming SIMD Extensions 3 (SSSE3)'''</small><br /> SSSE3的位可以在CPUID page 1的ECX位9中找到。 =====SSE4===== <small>'''Streaming SIMD Extensions 4 (SSE4)'''</small><br /> SSE4.1的位可以在CPUID page 1的ECX位19中找到 SSE4.2的位可以在CPUID page 1的ECX位20中找到 SSE4A的位可以在CPUID page 1的ECX位6中找到 =====SSE5===== <small>'''Streaming SIMD Extensions 5 (SSE5)'''</small><br /> SSE5计划作为一个单元,但分成了几个: ======XOP====== XOP的位可以在CPUID page 1的ECX位11中找到 ======FMA4====== FMA4的位可以在CPUID page 1的ECX位16中找到 ======CVT16====== CVT16的位可在CPUID page 1的ECX位29中找到 ======AVX====== AVX的位可以在CPUID page 1的ECX位28中找到 ======XSAVE====== XSAVE (管理扩展处理器状态所需) 的位可以在CPUID page 1的ECX位26中找到 ======AVX2====== The bit for AVX2 can be found on CPUID page 7, 0, in EDX bit 26 =====AVX-512===== The bits for AVX-512 are in CPUID page 0x0D, 0x0, EAX bits 5-7 ===X86_64=== 当[[X86-64]]体系结构推出时,AMD要求最低级别的SSE支持,以简化操作系统代码。 任何支持长模式的系统都应该至少支持SSE和SSE2,这意味着内核不需要关心旧的FPU保存代码。 X86-64将8个SSE寄存器 (xmm8 - xmm15) 添加到混合中。 但是,您只能在64位模式下访问这些。 '''Advanced Vector Extensions(高级矢量扩展)'''是英特尔于2011年推出的‘’SIMD‘’(单指令、多数据)指令集。 === AVX === AVX需要内核启用后才能使用。 忘记这样做会在第一次AVX通话时引发#UD。 在允许之前,必须同时启用SSE和OSXSAVE。 如果不这样做,也会产生一个#UD。 AVX通过设置XCR0寄存器的第2位启用。 还必须设置XCR0的位1(表示支持SSE)。 以下是启用SSE后启用AVX的汇编代码示例 (您应该首先检查AVX和XSAVE是否支持,请参见上文): <source lang="asm"> enable_avx: push rax push rcx push rdx xor rcx, rcx xgetbv ;Load XCR0 register or eax, 7 ;Set AVX, SSE, X87 bits xsetbv ;Save back to XCR0 pop rdx pop rcx pop rax ret </source> 要启用AVX-512,请设置XCR0的OPMASK(位5)、ZMM_Hi256(位6)、Hi16_ZMM(位7)。 您必须首先确保这些位有效(见上文)。 == 另见 == * [[MMX]] * The [[User:01000101/optlib/|optimisation library]] of 01000101, containing example code ===参考资料=== * The [[Wikipedia:EN:Streaming_SIMD_Extensions|Wikipedia article]] on SSE * The [[Wikipedia:EN:AVX-512|Wikipedia article]] on AVX-512 [[Category:X86]]
本页使用的模板:
模板:Floats
(
查看源代码
)
模板:If
(
查看源代码
)
模板:Show1
(
查看源代码
)
模板:SmallNavBox
(
查看源代码
)
返回至“
SSE
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息