Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14498062
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:33:26

下载本文示例代码
  在64位计算已越来越近的今天,越来越多的程序已开始考虑利用64位所带来的强大优势,其中,64位寻址对那些需要处理大量数据的应用程序来说尤为重要,如:工程与科学计算程序、大型数据库之类,现在已有许多的CPU及操作系统可本地支持64位计算,但它们带来的最大好处也许还是巨大的寻址空间,程序在其中可分配大于4GB的内存,更容易管理大文件等等。如果要充分发挥64位CPU的威力,应用程序还必须要利用64位中更宽的机器字,在本文中,将集中讨论64位上的程序性能优化。   64位的差异  不幸的是,如今的大多数软件都没有充分利用64位微处理器,以至于不能在64位模式下编译和运行,从而,软件被迫运行在32位兼容模式中--真是对硅的浪费。此外,还有很多程序员在用C语言编程时"玩忽职守",脑袋中想像着64位CPU,却用32位系统的模式来编程,以下是常见的情况:  ·以为指针与int大小一样。在64位系统中,sizeof(void *) == 8,而sizeof(int) == 4。如果忘记了这个,将导致不正确的赋值以致程序崩溃。  ·依赖于某一机器字架构的特定字节序。  ·使用long类型并假定它总是与int有同样大小。由此的直接赋值将导致数值截断,并且问题很难察觉。  ·堆栈变量的对齐方式。在一些情况中,堆栈变量也许不是按8字节边界对齐,如果你把这些变量转换成64位变量,在某些系统上,将会遇到一些麻烦。但是如果你在堆栈上放置一个64位变量(long或double),这保证是对齐的;还有,堆中分配的内存也是对齐的。  ·不同的对齐方式决定了结构与类的对齐。在64位架构上,结构成员通常对齐于64位边界,当在通过IPC、网络、或磁盘共享二进制数据时,就会有些问题;另外在包装数据结构以便存储资源时,没有考虑到对齐方式,同样也会有问题。  ·指针算法。当把一个64位指针像32位指针那样递增时(反之亦然),64位指针每次递增8字节,而32位指针每次递增4字节。  ·在缺少函数原型的情况下,返回值一般为int,这在某些时候也会导致数值截断。  并行编程:充分利用每次循环  64位C语言编程的高性能关键所在,是更宽的整数与FPU寄存器。CPU寄存器位于"食物链"的顶层--也是计算机存储器最昂贵部分所在,在64位CPU上,寄存器字宽通常为8字节,而对应的是常见的128位或256位内存总线带宽。  图1表示了32位系统的典型操作,CPU一次只都处理4字节内存中的数据。图2显示了有着更宽寄存器的64位系统,一次能处理8字节。 图1 图2  例1在某一内存块上进行XOR操作,其表示了一个基于整数的位集,你能在64位模式中对此进行优化。例2依赖于long long的C语言类型,但不会被某些编译器所支持。正如你所看到的,此处没有改变位集的总体大小,即使只花了较少的两次操作来重组矢量。例2有效地减少了循环的开销,相当于带系数2的循环展开,而只有一小点不利之处,就是它是纯64位的,如果在32位系统上编译,将会因为long大小的不同而给出错误的结果。  例1: { int a1[2048]; int a2[2048]; int a3[2048]; for (int i = 0; i < 2048; i) {  a3[i] = a1[i] ^ a2[i]; }}  例2: { long long a1[1024]; long long a2[1024]; long long a3[1024]; for (int i = 0; i < 1024; i) {  a3[i] = a1[i] ^ a2[i]; }}  你还能作进一步的修改,如例3所示,其利用了更宽的寄存器在32位和64位CPU上做同样的工作,在做如此的类型转换时,请注意指针对齐方式。如果你只是盲目地把int指针转换为64位long指针,指针地址将不会是8字节对齐的,在某些架构的机器上,还可能导致程序崩溃,或者带来性能损失。例3中的代码是不安全的,因为放置在堆栈中的32位int变量有可能4字节对齐,由此导致程序崩溃,如果在堆中分配(malloc),就能防止此类事情的发生。  例3: { int a1[2048]; int a2[2048]; int a3[2048]; long long* pa1 = (long long*) a1; long long* pa2 = (long long*) a2; long long* pa3 = (long long*) a3; for (int i = 0; i < sizeof(a1) / sizeof(long long); i) {  pa3[i] = pa1[i] ^ pa2[i]; }}共3页。 1 2 3 :   在64位计算已越来越近的今天,越来越多的程序已开始考虑利用64位所带来的强大优势,其中,64位寻址对那些需要处理大量数据的应用程序来说尤为重要,如:工程与科学计算程序、大型数据库之类,现在已有许多的CPU及操作系统可本地支持64位计算,但它们带来的最大好处也许还是巨大的寻址空间,程序在其中可分配大于4GB的内存,更容易管理大文件等等。如果要充分发挥64位CPU的威力,应用程序还必须要利用64位中更宽的机器字,在本文中,将集中讨论64位上的程序性能优化。   64位的差异  不幸的是,如今的大多数软件都没有充分利用64位微处理器,以至于不能在64位模式下编译和运行,从而,软件被迫运行在32位兼容模式中--真是对硅的浪费。此外,还有很多程序员在用C语言编程时"玩忽职守",脑袋中想像着64位CPU,却用32位系统的模式来编程,以下是常见的情况:  ·以为指针与int大小一样。在64位系统中,sizeof(void *) == 8,而sizeof(int) == 4。如果忘记了这个,将导致不正确的赋值以致程序崩溃。  ·依赖于某一机器字架构的特定字节序。  ·使用long类型并假定它总是与int有同样大小。由此的直接赋值将导致数值截断,并且问题很难察觉。  ·堆栈变量的对齐方式。在一些情况中,堆栈变量也许不是按8字节边界对齐,如果你把这些变量转换成64位变量,在某些系统上,将会遇到一些麻烦。但是如果你在堆栈上放置一个64位变量(long或double),这保证是对齐的;还有,堆中分配的内存也是对齐的。  ·不同的对齐方式决定了结构与类的对齐。在64位架构上,结构成员通常对齐于64位边界,当在通过IPC、网络、或磁盘共享二进制数据时,就会有些问题;另外在包装数据结构以便存储资源时,没有考虑到对齐方式,同样也会有问题。  ·指针算法。当把一个64位指针像32位指针那样递增时(反之亦然),64位指针每次递增8字节,而32位指针每次递增4字节。  ·在缺少函数原型的情况下,返回值一般为int,这在某些时候也会导致数值截断。  并行编程:充分利用每次循环  64位C语言编程的高性能关键所在,是更宽的整数与FPU寄存器。CPU寄存器位于"食物链"的顶层--也是计算机存储器最昂贵部分所在,在64位CPU上,寄存器字宽通常为8字节,而对应的是常见的128位或256位内存总线带宽。  图1表示了32位系统的典型操作,CPU一次只都处理4字节内存中的数据。图2显示了有着更宽寄存器的64位系统,一次能处理8字节。 图1 图2  例1在某一内存块上进行XOR操作,其表示了一个基于整数的位集,你能在64位模式中对此进行优化。例2依赖于long long的C语言类型,但不会被某些编译器所支持。正如你所看到的,此处没有改变位集的总体大小,即使只花了较少的两次操作来重组矢量。例2有效地减少了循环的开销,相当于带系数2的循环展开,而只有一小点不利之处,就是它是纯64位的,如果在32位系统上编译,将会因为long大小的不同而给出错误的结果。  例1: { int a1[2048]; int a2[2048]; int a3[2048]; for (int i = 0; i < 2048; i) {  a3[i] = a1[i] ^ a2[i]; }}  例2: { long long a1[1024]; long long a2[1024]; long long a3[1024]; for (int i = 0; i < 1024; i) {  a3[i] = a1[i] ^ a2[i]; }}  你还能作进一步的修改,如例3所示,其利用了更宽的寄存器在32位和64位CPU上做同样的工作,在做如此的类型转换时,请注意指针对齐方式。如果你只是盲目地把int指针转换为64位long指针,指针地址将不会是8字节对齐的,在某些架构的机器上,还可能导致程序崩溃,或者带来性能损失。例3中的代码是不安全的,因为放置在堆栈中的32位int变量有可能4字节对齐,由此导致程序崩溃,如果在堆中分配(malloc),就能防止此类事情的发生。  例3: { int a1[2048]; int a2[2048]; int a3[2048]; long long* pa1 = (long long*) a1; long long* pa2 = (long long*) a2; long long* pa3 = (long long*) a3; for (int i = 0; i < sizeof(a1) / sizeof(long long); i) {  pa3[i] = pa1[i] ^ pa2[i]; }}共3页。 1 2 3 : 下载本文示例代码


64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧64位程序开发中的性能优化技巧
阅读(108) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~