64位平台的介绍

  1. IA-64 is a 64-bit microprocessor architecture developed by Intel and Hewlett Packard companies together. It is implemented in Itanium and Itanium 2 microprocessors. To learn more about the architecture IA-64 see the following Wikipedia article "Itanium".
  2. Intel 64 (EM64T / AMD64 / x86-64 / x64) is an extension of x86 architecture with full backward compatibility. There are many variants of its name, and it causes some confusion, but all these names mean the same thing: x86-64, AA-64, Hammer Architecture, AMD64, Yamhill Technology, EM64T, IA-32e, Intel 64, x64. To learn how so many names appeared see the article in Wikipedia: "X86-64".

64位平台的优势

  • 64-bit address space;
  • an extended register set;
  • a command set familiar to developers;
  • capability to launch obsolete 32-bit applications in a 64-bit operating system;
  • capability to use 32-bit operating systems.

Win64 Program model

Like in Win32, the size of a page in Win64 is 4 Kbytes. The first 64 Kbytes of the address space are never displayed, so the lowest correct address is 0x10000. Unlike Win32, system DLL's take more than 4 Gbytes.

Compilers for Intel 64 have one peculiarity: they can use registers with great efficiency to pass parameters into functions, instead of using the stack. This allowed the Win64 architecture developers to get rid of notions such as a calling convention. In Win32, you may use various conventions: __stdcall, __cdecl, __fastcall, etc. In Win64, there is only one calling convention. Here is an example of how four arguments of integer type are passed through registers:

  • RCX: the first argument
  • RDX: the second argument
  • R8: the third argument
  • R9: the fourth argument

The arguments following the first four integers are passed through the stack. To pass float arguments XMM0-XMM3 registers are used as well as the stack.

The difference in the calling conventions makes it impossible to use both 64-bit and 32-bit code in one program. In other words, if an application has been compiled for the 64-bit mode, all the libraries (DLL) being used must also be 64-bit.

Passing parameters through registers is one of the innovations that make 64-bit programs faster than 32-bit ones.


64位平台应用程序的性能

After being recompiled for a 64-bit system a program can use huge amounts of memory and its speed will increase in 5-15%. 5-10% of speed gain is achieved due to architectural features of the 64-bit processor, for example, a larger number of registers. And another 1-5% performance gain is determined by the absence of the WoW64 layer that translates calls between 32-bit applications and the 64-bit operating system.

For example, Adobe company says that a new 64-bit "Photoshop CS4" is 12% faster than its 32-bit version".


64位平台下容易犯的错误

  1. sizeof()的返回值在64位平台下占用8bytes,而不是32位平台下的4bytes;
  2. size_t类型,指针类型等在64位平台下占用8bytes,而不是32位平台下的4bytes;
  3. printf函数中,“%d” “%u” “%x”等模式只能打印出32bit类型的数,如果要打印出64bit的数,需要添加"I"(Windows平台)或“z”(Linux平台),譬如“%Id” “%Iu” “%Ix”,“%zd” “%zu” “%zx”;
  4. 整数常量,譬如 1, 在64位平台下的类型属于 int,因此占用4bytes,那么在进行移位操作时,需要注意这一点;
  5. 移位操作时,被移位的变量会被先强制转换成signed,然后进行移位操作,譬如下面的代码:  
struct BitFieldStruct {
unsigned short a:;
unsigned short b:;
};
BitFieldStruct obj;
obj.a = 0x4000;
size_t addr = obj.a << ; //Sign Extension
printf("addr 0x%Ix\n", addr);
//Output on 32-bit system: 0x80000000
//Output on 64-bit system: 0xffffffff80000000
// obj.a is converted into signed int before shift.
  1. 地址加法时,很容易出错,譬如如下代码

    int A = -;
    unsigned B = ;
    int array[] = { , , , , };
    int *ptr = array + ;
    ptr = ptr + (A + B); //Invalid pointer value on 64-bit platform
    printf("%i\n", *ptr); //Access violation on 64-bit platform

    原因如下:  

Let us follow the algorithm of calculating the expression "ptr + (A + B)":

  • According to C++ rules, the variable A of the type int is converted to unsigned.
  • A and B are summed and we get the value 0xFFFFFFFF of unsigned type.
  • The expression "ptr + 0xFFFFFFFFu" is calculated.

The result of this process depends upon the size of the pointer on a particular architecture. If the addition takes place in the 32-bit program, the expression is equivalent to "ptr - 1" and the program successfully prints the value "3". In the 64-bit program, the value 0xFFFFFFFFu is fairly added to the pointer. As a result, the pointer gets far outside the array while we encounter some troubles when trying to get access to the item by this pointer.

Like in the first case, we recommend you to use only memsize-types in pointer arithmetic to avoid the situation described above. Here are one ways to correct the code:

ptr = ptr + (ptrdiff_t(A) + ptrdiff_t(B));
ptrdiff_t A = -;
size_t B = ;
...
ptr = ptr + (A + B);

指针类型的强制转换也容易导致错误

int array[] = { , , ,  };
enum ENumbers { ZERO, ONE, TWO, THREE, FOUR };
//safe cast (for MSVC)
ENumbers *enumPtr = (ENumbers *)(array);
cout << enumPtr[] << " ";
//unsafe cast
size_t *sizetPtr = (size_t *)(array);
cout << sizetPtr[] << endl;
//Output on 32-bit system: 2 2
//Output on 64-bit system: 2 17179869187=0x0000000400000003

原因:在64-bit系统中,size_t 占8bytes,因此,sizetPtr[1]指向的是内存各占4btyes的数字3和4拼接起来的内存块,也就是0x0000000400000003


Storage of integer values in double

size_t a = size_t(-);
double b = a;
--a;
--b;
size_t c = b; // x86: a == c
// x64: a != c

原因:

This code may be justified when it is executed on a 32-bit system because the type double has 52 significant bits and can store a 32-bit integer value without loss. But when you save a 64-bit integer number into double, the exact result will be lost.


结构体占用的内存字节数

struct MyStruct
{
bool m_bool;
char *m_pointer;
int m_int;
}; // x86: sizeof(MyStruct) = 12
// x64: sizeof(MyStruct) = 24
struct MyStruct
{
char *m_pointer;
int m_int;
bool m_bool;
}; // x86: sizeof(MyStruct) = 12
// x64: sizeof(MyStruct) = 16

【 字节对齐的窍门】:The process of optimizing a field arrangement may seem complicated. But there is a very simple and very effective method: you just need to arrange the fields in decreasing order of their sizes. 


64位平台的劣势:内存开销偏大

When a program is compiled in the 64-bit mode, it starts consuming more memory than its 32-bit version. This increase often stays unnoticed, but sometimes memory consumption may grow twice. The growth of memory consumption is determined by the following factors:

  • larger memory amounts to store some objects, for example pointers;
  • changes of the rules of data alignment in structures;
  • growth of stack memory consumption.

We can often tolerate the growth of main memory consumption - the advantage of 64-bit systems is that very large amount of memory available to user. It is quite okay if a program takes 300 Mbytes on a 32-bit system with 2 Gbytes of memory and 400 Mbytes on a 64-bit system with 8 Gbytes of memory. In relative units, it means that the program takes three times less memory available on a 64-bit system. So it is unreasonable to strike against the growth of memory consumption we have described - it is easier to add just a bit more memory.

But there is a disadvantage of this growth. It is related to performance loss. Although the 64-bit program code is faster, extraction of larger data amounts from memory might cancel all the advantages and even reduce performance. The operation of transferring data between the memory and microprocessor (cache) is not very cheap.

One of the ways to reduce the memory being consumed is optimization of data structures we have told you about in Lesson 23.

Another way of saving memory is to use more saving data types. For instance, if we need to store a lot of integer numbers and we know that their values will never exceed UINT_MAX, we may use the type "unsigned" instead of "size_t".


[参考文献]:

  1. 64位平台C/C++开发注意事项
  2. Lessons on the development of 64-bit C/C++ applications

64位平台C/C++容易犯的错误的更多相关文章

  1. SWMM代码移植到64位平台

    在32位平台上运行SWMM模型,当节点数量到达60万以上的时候,模型运行占用内存接近1.85G的时候就会因为内存不够而无法计算.这种情况还是单独运行SWMM.exe的时候出现,如果采用SWMM.DLL ...

  2. 64位平台C/C++开发注意事项(转载)

    转自http://coolshell.cn/articles/3512.html 在http://www.viva64.com/en/l/上例出了28个在64位平台上使用C/C++开发的注意事项,对于 ...

  3. 64位平台支持大于2 GB大小的数组

    64位平台支持大于2 GB大小的数组 64位平台.NET Framework数组限制不能超过2GB大小.这种限制对于需要使用到大型矩阵和向量计算的工作人员来说,是一个非常大问题. 无论RAM容量有多大 ...

  4. 64位平台C/C++开发注意事项

    在http://www.viva64.com/en/l/上例出了28个在64位平台上使用C/C++开发的注意事项,对于进入64位时代的程序员应该去看看这28个事项,这些英文读物对于有C/C++功底的朋 ...

  5. NET Framework 4.5新特性 (三)64位平台支持大于2 GB大小的数组

    64位平台.NET Framework数组限制不能超过2GB大小.这种限制对于需要使用到大型矩阵和向量计算的工作人员来说,是一个非常大问题. 无论RAM容量有多大有多少,一旦你使用大型矩阵和向量计算工 ...

  6. 手把手教你写Windows 64位平台调试器

    本文网页排版有些差,已上传了doc,可以下载阅读.本文中的所有代码已打包,下载地址在此. ------------------------------------------------------- ...

  7. win7 64位平台编译的程序在XP 32位平台无法运行的解决方法

    win7 64位平台编译的程序在XP 32位平台无法运行的解决方法 vs2010的开发环境,制作了一个DLL库.但DLL在XP 32位平台一直无法使用.解决方法如下: 右键项目,属性->配置属性 ...

  8. 查看Pyton的版本号和32/64位平台

    怎么查看Python的版本号?使用的Python是32位还是64位的?用以下两条Python 指令就可以知道. 方法1:通过Python代码查看 import platform import sys ...

  9. xsocks 64位平台下编译问题小记

    1.src/common/public.h uint32_t lpParameter 改为 void* lpParameter; 2.SocksMgr.cpp DWORD WINAPI CSocksM ...

随机推荐

  1. 学习SpringMVC——拦截器

    拦截器,顾名思义就是用来拦截的. 那什么是拦截,又为什么要拦截.对于Spring MVC来说,拦截器主要的工作对象就是用户的请求,拦截下来之后,我们可以在拦截的各个阶段悉心呵护[为所欲为].常见的比如 ...

  2. [LeetCode] Fizz Buzz 嘶嘶嗡嗡

    Write a program that outputs the string representation of numbers from 1 to n. But for multiples of ...

  3. 表达式括号匹配(stack)

    题目描述 假设一个表达式由英文字母(小写).运算符(+.-.*./)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右括号是否匹配,若匹配,则返回“YES”:否则返回 ...

  4. POJ 2337 Catenyms(有向图的欧拉通路)

    题意:给n个字符串(3<=n<=1000),当字符串str[i]的尾字符与str[j]的首字符一样时,可用dot连接.判断用所有字符串一次且仅一次,连接成一串.若可以,输出答案的最小字典序 ...

  5. 安装SQL SERVER开启SA用户登录的方法

    家庭安装SQL SERVER开启SA用户登录的方法:(切记按照网址操作完后,最后一定要在"管理工具"的"服务"里把"SQL SERVER(MSSQL ...

  6. 周赛-Expression 分类: 比赛 2015-08-02 09:35 3人阅读 评论(0) 收藏

    A. Expression time limit per test1 second memory limit per test256 megabytes inputstandard input out ...

  7. grok 正则捕获(就是perl的正则捕获)

    2.3.2 grok 正则捕获: \s+ 和 [\n\t\r\f]+ 一样 1.命名分组格式为(?<grp name>),反向引用时用\k<grp name> 2.命名分组的匹 ...

  8. 云计算(2)it 是什么

    2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...

  9. OpenCV +Python 制作画板

    效果图 画图工具实现 代码 运行结果 程序分析 窗体自由度 如何退出程序 滚动条相关 支持的事件 首先声明一下,本例思路不是博主原创,博主在前人的代码上进行了个性化的修改,制作了一个简单的画图工具.下 ...

  10. 【LOJ6074】【2017 山东一轮集训 Day6】子序列 DP

    题目描述 有一个由前 \(m\) 个小写字母组成的串 \(S\),有 \(q\) 个询问,每次给你 \(l,r\),问你 \(S_{l\ldots r}\) 有多少个非空子序列. \(m=9,n=\l ...