怎样优化Pentium系列处理器的代码.doc

上传人:工**** 文档编号:558305711 上传时间:2024-02-15 格式:DOC 页数:17 大小:172.50KB
返回 下载 相关 举报
怎样优化Pentium系列处理器的代码.doc_第1页
第1页 / 共17页
怎样优化Pentium系列处理器的代码.doc_第2页
第2页 / 共17页
怎样优化Pentium系列处理器的代码.doc_第3页
第3页 / 共17页
怎样优化Pentium系列处理器的代码.doc_第4页
第4页 / 共17页
怎样优化Pentium系列处理器的代码.doc_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《怎样优化Pentium系列处理器的代码.doc》由会员分享,可在线阅读,更多相关《怎样优化Pentium系列处理器的代码.doc(17页珍藏版)》请在金锄头文库上搜索。

1、怎样优化Pentium系列处理器的代码Copyright 1996, 2000 by Agner Fog. Last modified 2000-07-03.云风 (Cloud Wu) 译 http:/ 翻译中.(13.3%) 目录1. 简介 2. 文献 3. 高级语言中调用汇编函数 4. 调试及校验 5. 内存模式 6. 对齐 7. Cache 8. 第一次 vs 重复运行 9. 地址生成互锁(AGI) (PPlain 及 PMMX) 10. 配对整数指令 (PPlain 及 PMMX) 1. 完美的配对 2. 有缺陷配对 11. 将复杂指令集分割为简单指令 (PPlain 及 PMMX)

2、12. 前缀 (PPlain 及 PMMX) 以下待译. 13. PPro, PII 及 PIII 流水线综述 14. 指令解码 (PPro, PII 及 PIII) 15. 取指令 (PPro, PII 及 PIII) 16. 寄存器重命名 (PPro, PII 及 PIII) 1. 消除依赖性 2. 寄存器读延迟17. 乱序执行 (PPro, PII 及 PIII) 18. 引退 (PPro, PII 及 PIII) 19. 部分(Partial)延迟 (PPro, PII 及 PIII) 1. 部分寄存器延迟 2. 部分标记延迟 3. 移位和旋转后的标记延迟 4. 部分内存延迟20. 依

3、赖环 (PPro, PII 及 PIII) 21. 寻找瓶颈 (PPro, PII 及 PIII) 22. 分支和跳转 (所有的处理器) 1. PPlain 的分支预测 2. PMMX, PPro, PII 及 PIII的分支预测 3. 避免跳转 (所有的处理器) 4. 避免使用标记的条件跳转 (所有的处理器) 5. 将条件跳转替换成条件赋值 (PPro, PII 及 PIII)23. 减少代码长度 (所有的处理器) 24. 规划浮点代码 (PPlain 及 PMMX) 25. 循环优化 (所有的处理器) 1. PPlain 及 PMMX 中的循环 2. PPro, PII 及 PIII 中的

4、循环26. 有问题的指令 1. XCHG (所有的处理器) 2. 带进位标记的循环移位 (所有的处理器) 3. 字符串指令 (所有的处理器) 4. 位测试 (所有的处理器) 5. 整数乘法 (所有的处理器) 6. WAIT 指令 (所有的处理器) 7. FCOM + FSTSW AX (所有的处理器) 8. FPREM (所有的处理器) 9. FRNDINT (所有的处理器) 10. FSCALE 及幂函数 (所有的处理器) 11. FPTAN (所有的处理器) 12. FSQRT (PIII) 13. MOV MEM, ACCUM (PPlain 及 PMMX) 14. TEST 指令 (P

5、Plain 及 PMMX) 15. Bit scan (PPlain 及 PMMX) 16. FLDCW (PPro, PII 及 PIII) 27. 特别主题 1. LEA 指令 (所有的处理器) 2. 除法 (所有的处理器) 3. 释放浮点寄存器 (所有的处理器) 4. 浮点指令与MMX 指令的转换 (PMMX, PII 及 PIII) 5. 浮点转换为整数 (所有的处理器) 6. 使用整数指令做浮点运算 (所有的处理器) 7. 使用浮点指令做整数运算 (PPlain 及 PMMX) 8. 数据块的移动 (所有的处理器) 9. 自修改代码 (所有的处理器) 10. 检测处理器类型 (所有的

6、处理器) 28. 指令速度列表 (PPlain 及 PMMX) 1. 整数指令集 2. 浮点指令集 3. MMX 指令集 (PMMX)29. 指令速度及微操作失败列表(PPro, PII 及 PIII) 1. 整数指令集 2. 浮点指令集 3. MMX 指令集 (PII 及 PIII) 4. XMM 指令集 (PIII) 30. 速度测试 31. 不同的微处理器间的比较 1. 简介这本手册细致的描述了怎样写出高度优化的汇编代码, 着重于讲解Pentium系列的微处理器. 这儿所有的信息都基于我的研究. 很多人为这本手册提供了有用的信息和错误矫正, 而我在获得任何新的重要信息后都更新它. 因此这

7、本手册比其它类似的信息来源都更准确,详尽,精确和便于理解, 而且它还包含了许多其它地方找不到的细节描述. 这些信息使你能够用多种方法精确统计一小段代码花掉的时钟周期数. 但是,我不能保证手册里所有的信息都是精确的: 一些时间测试等是很难或者不可能精确测量的, 我看不到 Intel 手册作者拥有的内部技术文档资料. 这本手册讨论了 Pentium 处理器的下列版本: 缩写名字PPlainplain 老式 Pentium (没有 MMX)PMMX有MMX的PentiumPProPentium ProPIIPentium II (包括 Celeron 和 Xeon)PIIIPentium III (

8、包括一些相当的CPU)这本手册中使用了MASM 5.10的汇编语法. 没有什么官方的 X86 汇编语言, 但这是最接近你能接受的标准, 因为几乎所有的汇编器都有 MASM 5.10 兼容模式. (然而我不推荐使用 MASM 的 5.10 版本. 因为它在 32 位模式下有严重的 Bug. 最好是使用 TASM 或者 MASM 的后续版本). 手册里的一些评语好象是对Intel的批评. 但这并不是说其它的产品会好一些. Pentium系列的微处理器能在评测分中取得更好一点的比较值,有更好的文档, 和更多的可测试特性. 由于这些原因, 不会有我或者其他人做同类商品的比较测试. 汇编语言编程比用高级

9、语言要复杂的多. 制造 Bug 是很容易的,但是找到 Bug 却很难. 现在已经提醒你了! 我假定读者已经有汇编编程的经验. 没有的话,请在做复杂的优化前读一些汇编的书并且写些代码获得些汇编的经验. PPlain 和 PMMX 芯片的硬件设计有许多专门为一些常用指令或者指令对设计的特性, 而不是使用那些一般的优化模块. 因此,为这个设计优化软件的规则很复杂, 且有很多的例外, 但是这样做可能获得实质性的好处. PPro, PII 和 PIII 处理器有非常不同的设计,它们会利用乱序执行来做许多的优化工作, 但是处理器的这些个设计带来了许多潜在的瓶颈, 因此为这些处理器进行手工优化将得到许多的好

10、处. Pentium 4 处理器也用了另外一种设计, 奔腾4 的优化指导路线和前面的版本非常的不同了. 这个手册没有禳括奔腾4 - 读者请自己查阅 Intel 的手册. 在把你的代码转为汇编的之前,确认你的算法是足够优化的. 通常你可以通过优化算法来将代码效率提高的比转成汇编获得的效率多的多. 第二,你必须找到你的程序里最关键的部分. 通常 99% 的 CPU 时间花在程序最里面的循环中. 在这种情况下, 你只要优化这个循环并把其它的所有东西都用高级语言写. 一些汇编程序员将大量的精力花在了他们程序的错误的部分上, 他们努力得到的唯一结果就是程序变的更加难以调试和维护了. 如果你的程序的关键部

11、分并不那么明显,你可以用profil来找. 如果发现瓶颈在磁盘操作, 然后你就可以试着修改程序使磁盘操作集中连续, 提高磁盘缓冲的命中率, 而不是用汇编来写代码. 如果瓶颈在图象输出,那么你就可以尝试找到一种方法来减少调用图象函数的次数. 一些高级语言编译器对于指定的处理器提供了相对好的优化, 但是手工优化将做的更好. 请不要将你的编程问题寄给我. 我不会帮你做家庭作业的! 祝你在后面的阅读中好运! 2. 文献在 Intel 的 www 站上,打印的文本或者 CD-ROM 上都有很多有用的文献和教程. 建议你研究一下这些文档来对微处理器的结构有些认识. 然而,Intel 的文档也不总是对的 -

12、 尤其是那些教程有很多错误(显然,Intel的那些人没有测试他们的例子). 这里我不给出 URL, 因为文件的位置经常的改变. 你可以利用 或者www.agner.org/assem 上的链接上的搜索工具找到你要的文档. 一些文档是.PDF格式的. 如果你没有显示或者打印PDF的工具, 可以去下载Acrobat 文件阅读器. 使用 MMX 和 XMM (SIMD) 指令优化专门的程序在几本使用手册里都有描述. 各种手册和教程都有描述其指令集. VTUNE 是 Intel 用来优化代码的软件工具我没有测试它,因此这里不于评价. 还有很多比 Intel 的更多的更有用的信息. 在新闻组 comp

13、.land.asm.x86 的 FAQ 里有把这些资源列出来. 其它的 internet 上的资源在 www.agner.org/assem 上也有链接. 3. 在高级语言里调用汇编函数你可以使用在线汇编或者用汇编写整个子程序然后再连接到你的工程中. 如果你选择后者, 建议你用可以将高级语言直接编译成汇编的编译器. 这样你可以得到函数的正确的调用原型. 所有的 C+ 编译器都能做这个工作. 传递参数的方法取决于调用形式:调用方式参数在堆栈里的次序参数由谁来移去_cdecl第一个参数在低位地址 调用者_stdcall第一个参数在低位地址子程序_fastcall编译器指定 子程序_pascal第一

14、个参数在高位地址 子程序函数调用原型和被编译器命名的函数名可能非常的复杂. 有很多不同的调用转换规则, 不同的编译器也互不兼容. 如果你从C+里调用汇编语言的子程序,最好的方法是将你的函数用 extern C 和 _cdel 定义来兼容性和一致性. 汇编代码的函数名前面必须带一个下划线 (_) 并且在外面编译时加上大小写敏感的选项 (选项 -mx). 例如: ; extern C int _cdecl square (int x); _square PROC NEAR ; 整型平方函数 PUBLIC _square MOV EAX, ESP+4 IMUL EAX RET _square END

15、P如果你需要重载函数,重载操作符,方法, 和其它 C+ 专有的东西, 就必须在 C+ 里先写好代码再用编译器编译成汇编代码以获得正确的连接信息和调用模型. 这些随着编译器的不同而不同而且很少列出文档. 如果你希望汇编函数用其它的调用原型而不是 extern C 及 _cdecl 的, 又可以被不同的编译器调用, 那么你需要为每个编译器写一个名字. 例如重载一个 square 函数: ; int square (int x); SQUARE_I PROC NEAR ; 整数 square 函数 square$qi LABEL NEAR ; Borland 编译器的连接名字 ?squareYAHHZ LABEL NEAR ; Mi

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号