首页 随笔 乐走天涯 程序资料 评论中心 Tag 论坛 其他资源 搜索 联系我 关于 RSS

MMX技术开发者手册:第四章 代码开发策略


日期: 2000-06-12 14:00 | 联系我 | 关注我: Telegram, Twitter

  通常,开发IA处理器上的高速应用并不困难。如对体系结构具有深入了解且有很好的开发经验,则可使开发的应用程序充分发挥潜力,提高运行速度,使之成为一个高速的应用程序。具有MMX™技术的Intel体系结构的处理器为开发增加了新的研究方向。通过不断发展的转换技术可将性能有效地提高。为了开发MMX™代码,应测试当前的设备并选择最佳方式,来发挥MMX™指令的优势。如果你正在进行一项开发工作,作为开始,请现在就使用MMX™技术设计应用程序。

4.1 制订计划

  无论是修改现有应用程序还是创建新的应用程序,在使用MMX™指令来达到最佳性能时,需要考虑几个方面的因素。通常要先找到计算集中的代码段,且该代码段应是可修改为整数实现的,并有效支持高速缓存的体系结构。Intel性能工具箱提供了几个工具来辅助进行判断和调整。

  在进行这些工作前,应先回答下列问题:

哪部分代码可用MMX™技术改进?

使用MMX™技术是否可使当前算法达到最佳?

代码是整型还是浮点型的?

如何安排数据?

代码是8位、16位还是32位的?

应用程序是否需同时在有MMX™技术和无MMX™技术的处理器上运行?是否可用CPUID来创建一个可自适应的实现?

4.2 哪部分代码可使用MMX™技术改进?

  第一步 判断转换哪部分代码

  大多数应用程序都有几个计算高度集中的代码段。例如,语言压缩算法和过滤器,视频显示例程和绘制着色例程。这些例程通常较小,有重复的循环,对8位或16位整数操作,且占用了应用程序相当大的处理时间。这些例程使用MMX™技术优化库代码进行转换可获得最大的性能提高。将这些循环封装到优化的MMX™技术库,无论是否具有MMX™技术的平台,都将更灵活地给予支持。作为性能优化工具,类如Intel的VTune可视化调试工具,可用于把计算集中的代码分离出来。一旦将这些代码找到,将判断当前算法和修改后的代码哪一个具有最佳性能。在某些情况下,可能会改变算法中某些类型的操作来提高性能。用MMX™指令性能来匹配算法是达到最佳性能的关键。

4.3 代码是浮点型还是整型?

  第二步 判断算法包含的是浮点型数据还是整型数据

  如果当前算法是用整型数据实现的,则可简单判断一下算法中占用大多数微处理器时钟周期的代码部分在哪里。一旦判断出来,可用MMX™指令重新实现这些部分。

  如果算法中存在浮点型数据,则判断一下使用浮点型数据的原因。使用浮点操作通常有以下几个原因:性能、范围和精确度。如果性能因素是算法使用浮点数的原因,那么可考虑用MMX™整型代码替换算术来提高性能。

  如果数据范围或精确度的因素是算法使用浮点数用于进一步适应可能的范围或精确度的要求。可考虑是否能用整型数据达到所要求的范围和精确度?如果不能,代码最好仍用浮点代码。

4.3.1 混用浮点和MMX™代码

  如果使用MMX™代码,需要牢记的一点是八个MMX™寄存器是浮点寄存器的别名。由MMX™指令切换为浮点指令将增加多达五十个时钟周期,因此最好将这种切换次数减少到最小。不要将MMX™代码和浮点代码在指令级进行内部混用。如果一个应用程序频繁地进行MMX™代码和浮点代码间的切换,可考虑将之修改为只用MMX™指令流或浮点指令流来最大限度地降低由切换带来的额外迟延。

  当需混用浮点指令或MMX™指令编写应用程序时,下列准则可用来分离指令执行:

将MMX™指令流和浮点指令流分为只包含单一类型代码的指令流。

在转换中,寄存器内容无效。

MMX™代码结束时,使用EMMS指令置浮点标志字为空。

浮点代码结束时,将堆栈置空。

  例如:

FP_Code:

...

...

... /*离开时,将浮点栈置空*/

MMX™_Code:

...

...

...

EMMS /*MMX™寄存器空*/

FP_Code1:

...

...

...

... /*离开时,将浮点栈置空*/

  有关浮点编程模型的其它内容,请参见《奔腾处理器系列开发者手册》第三卷,体系结构和编程(序号241430)。

4.4 EMMS准则

  第三步 在MMX™代码结束时必须使用EMMS指令

  由于MMX™寄存器是浮点寄存器的别名,故一定要在使用浮点指令前,清空MMX™寄存器。使用EMMS指令清MMX™寄存器并置浮点标志字(TW)的值为空(即为全1)。该指令应在每个MMX™代码段的结束时插入,以避免执行浮点代码时产生浮点栈的溢出错误。

4.5 CPUID的检测MMX™技术的用法

  第四步 判断是否具有MMX™技术

  可用两种方法在应用程序中使用MMX™技术:第一种方法是在应用程序安装时检测是否具有MMX™技术。如果具有MMX™技术,则可安装相应的库代码。第二种方法是在程序执行时检测,并于运行时刻装人合适的库代码,这对于网络上的程序非常有效。

  为判断你的处理器是否具有MMX™技术,应用程序应检测Intel体系结构的特性标志。CPUID指令将特性标志返回到EDX寄存器中,程序可基于这一结果为系统选择合适的执行代码。

  特征标志字的第23位指示是否具有MMX™技术。当该位为1时,表示具有MMX™技术。下列代码段从特性标志字中提取值到EDX中,并检测是否具有MMX™技术。有关CPUID用法的其它内容请详见《用CPUID指令识别Intel处理器》应用程序部分AP-485,(序号241618)。

... ;CPUID指令识别是否具有MMX™

... ;识别Intel处理器

...

...

MOV EAX, 1 ;调用申请特性标志

CPUID ;0FH,A2H,CPUID指令

test EDX, 00800000H ;在特性标志位(23位)=1时为MMX™技术存在

JNZ Found

4.6 数据对齐

  第五步 确定数据己对齐

  很多编译器允许通过控制来指定对齐变量。通常可使变量按合适的边界对齐。但是,如果你发现有些变量未按指定边界取齐。清使用下列C语言写的算法对齐变量。这是按64位边界来对齐64位变量,一旦对齐后,对该变量的每次访问将节省3个时钟周期。

if(NULL==(new_ptr=malloc(new_value+1)*sizeof(var_struct))

mem_tmp=new_ptr;

mem_tmp/=8;

new_tmp_ptr=(var_struct*)((Mem_tmp+1)*8);

  另一种改进数据对齐的方法是将数据复制到己按64位边界对齐的地址中。当数据访问频繁时,可有效地提高性能。

4.6.1 堆栈对齐

  常规情况下,编译器对非静态的数据都分配到堆栈,而且通过存贮于堆栈的64位数据很方便地实现。如果可能,一定要使堆栈对齐。下列代码是使堆栈时齐的起始函数和结束函数。

Prologue:

push ebp ;保存IH的帧指针

mov ebp, sep ;生成新的帧指针

sub ebp, 4 ;建立栈指针的空iBq

and ebp, 0FFFFFFC ;按64位对齐

mov [ebp], esp ;保存旧的栈指针

mov esp, ebp ;复制对齐的指针

sub esp, FRAMESIZE ;分配空间

... callee saves, etc

epilogue:

... callee restores, etc

mov esp, [ebp]

pop ebp

ret

  对那些频繁访问而又无法对齐的数据,可将它们复制到已对齐的存贮空间去。

4.7 数据安排

  MMX™技术利用SIMD技术,来开发大多数多媒体算法中固有的并行机制。为了利用MMX™代码提高性能,内存中的数据应按下列准则进行格式化。

  请考虑一个将16位偏置数据加到一个向量的全部16位元素上的简单例子。在常规标量代码中,在循环开始时将偏置数据读入一个寄存器。在另一个寄存器中访问向量元素,并且一次只完成一条加法。

  将例程改换成MMX™代码后,由于MMX™指令可通过MOVQ指令一次处理四个向量元素,并通过PADDW指令一次完成四个加法。将使速度提高四倍。但是为了达到这一速度,在做加法时需要将偏置数据复制四份放在MMX™寄存器中。

  在原始的标量代码中,只有一个偏置数据位于内存。用MMX™指令可通过不同方法将四个偏置数据的备份放人MMX™寄存器中,或者通过预先对内存格式化,复制四个偏置数据。然后,只需在循环开始时,用MOVQ指令读取这些备份数据,就可使速度提高四倍。关于这种数据安排的另一个有趣的例子请详见第5.6节。

  由MMX™技术定义的新型64位成组数据类型可通过对未对齐数据进行优化而发挥更大能力。在使用MMX™指令和其它成组数据类型时,有很多算法。因为有的数据访问模式是未对齐的,如FIR过滤器这样一个简单的例子。F1R是一个按分支系数的数量长度产生有效的向量过滤器。如果过滤器对数据元素i的操作是一个从数据元素j开始产生的向量点(data[j]*coeff[0]+data[j+1]*coeff[1]+...+data[j+num_of_taps-1]*coeff[num_of_taps-1]),那么过滤器对数据元素i+1的操作开始于数据元素j+1。

  4.6节说明了64位内存数据对齐问题。假设你有一个已对齐的64位数据向量和一个已对齐的64位系数向量,则过滤器对第一个数据的操作是对齐的,但对第二个数据元素的操作时,每个对数据向量的访问将是未对齐的!对数据结构的复制和填充将避免算法中固有的访问未对齐数据的问题。在《MMX™指令计算一个16位实数FIR过滤器》应用部分#559(序号243044)中有一个说明如何避免FIR过滤器中未对齐问题的例子。

  注意复制和填充技术解决了未对齐问题,但要避免由于增大了数量,而造成未对齐数据访问的额外开销增大。在开发你的代码时,应考虑这种交换并通过选择开关来达到最佳性能。

4.8 应用程序最后的调节

  一旦应用程序的功能正确后,最佳的调节方法是使用一个分析器来检测在系统中运行的应用程序。Intel的VTune可视化微调工具就是这样一个工具,它要帮助你判断在你的应用程序中修改何处的代码可提高性能。另外,1nte1处理器提供了一个在片性能计数器,第6.1节中将说明这个计数器并解释如何使用它们。

标签: MMX 优化

 文章评论
目前没有任何评论.

↓ 快抢占第1楼,发表你的评论和意见 ↓

发表你的评论
如果你想针对此文发表评论, 请填写下列表单:
姓名: * 必填 (Twitter 用户可输入以 @ 开头的用户名, Steemit 用户可输入 @@ 开头的用户名)
E-mail: 可选 (不会被公开。如果我回复了你的评论,你将会收到邮件通知)
反垃圾广告: 为了防止广告机器人自动发贴, 请计算下列表达式的值:
6 x 4 + 5 = * 必填
评论内容:
* 必填
你可以使用下列标签修饰文字:
[b] 文字 [/b]: 加粗文字
[quote] 文字 [/quote]: 引用文字

 
首页 随笔 乐走天涯 猎户星 Google Earth 程序资料 程序生活 评论 Tag 论坛 资源 搜索 联系 关于 隐私声明 版权声明 订阅邮件

程序员小辉 建站于 1997 ◇ 做一名最好的开发者是我不变的理想。
Copyright © XiaoHui.com; 保留所有权利。