一、计算机的发展
计算机从二进制为基础开始描述整个世界,但正如现实世界一样,十进制为主的世界也会有万千百概念。所以在实际的应用中,会出现32位和64位的计算机系统。当然,前面还有过16位、8位和4位等,以后还可以会出现128位和256位甚至更高也不是没可能。怎么理解它们呢?先举一个不太形象的比喻。现实世界中的GDP的单位一般是万亿元为单位;大公司的利润一般是以亿元为单位,中小公司的利润一般是以万元为单位;而个人的收入一般是以元为单位。明白了吧。
在看韩国的电视剧时,经常有介绍对象的情况,中间人会说,男方非常优秀,年收入亿元。可以简单理解为这就是货币发展了,所以收入“提高”了。
同理,计算机也是如此,以前直接使用二进制处理数据就可以轻松的应对大多数的工作。但随着计算机技术的发展和应用的不断提高,对使用计算机来描述应用的要求也不断提高,为了能更好的适应这个改变,一种方法就是增加系统能表达的能力,也即从单纯的处理两位增加到64位。什么意思呢?就是处理数据的宽度从2位增加到64位,处理的数据大了,处理的速度也就快了。也可以理解为处理数据从一个基础单元到小的逻辑块(4、8),中型的逻辑块(16、32)再到大的逻辑块64位。
二、32位到64位
这里只从现在普遍使用的32和64位谈起,更早的因为几乎已经不可能再遇到了,故而不再赘述。
通过上面的初步分析,可能大多数人有了一个基础的印象,但可能仍然还是有些不清晰。再举一个例子,假如开发一个项目,需求中有一个要求是显示几千万亿的数据,如果是32位的系统,开发者可能需要做一些特殊的处理,才能显示(int32范围:2147483648~2147483647,类似long long这种是底层处理的)。 但是在64位的系统中就可以直接使用int64来表示,使用起来方便了很多。 但从32位到64位不是很多人想象的一个简单的数据宽度的变化。它是一个系统的工程,从CPU到寄存器,从内存,到总线等等的硬件都需要升级或匹配。单单是CPU指令集都是一个复杂的工程。
三、问题的提出
从32位到64位,最麻烦的不是实现,而是相关资料的不完善性。大家都知道,从32位系统到64位系统的发展不是一夜之间完成的,它经历一个相当长的时期,以至于到现在,仍然有大量的32位电脑在互联网上运行(可以看一下XP系统的数量)。反倒是后来的手机系统,基本都是64位的系统了,这就是后发者的优势。但这也带来了大量的问题,最重要的之一就是相关的64位的资料不完整、不完善甚至很多都已经陈旧。同样,在此基础上大量的相关工具也没有随着系统的进步而进步。下面就对这两个主要的问题分析说明一下:
1、陈旧的资料
资料的陈旧在网上和资料中非常常见,一个最主要的例子就是在编程的书籍中仍然使用循环来处理大数组,看下面的代码:
constexpr int64_t len = 1000*1000*1000;
Array[len] = {0};
for (int64_t id = 0;id < len;id++){Array[id] = id +100;
}
现在假设的长度为10个亿,一般来说在32位的系统上足够了。可如果到了64位的平台呢?在现在互联网上大的数组应用比比皆是。如果说上面的代码有些暴力,那么有一些代码可能就更容易出现问题:
for (int i = 0; i != width; ++i){for (int j = 0; j != height; ++j){for (int k = 0; k != depth; ++k){Array[k * width * height + j * width + i] = v;}}}
可能大多数开发者看到这段代码觉得没有什么,但是其实它并没有考虑大数组的情况(和上面的情况一致)。即如果数组的长度超过32位系统的长度会如何呢?所以解决这类的问题的方法应该是使用size_t,让系统自动去处理这些长度,而不是使用传统的int。同样,64位系统的演进是从硬件和底层开始的,那么直接面对它们的编程语言是汇编和C居多,抛除汇编,现在大多的64位资料多是以C为原型说明的,但现在应用上一直是用C++在不断的替代C,而针对C++相关的64位资料则相对较少。而随着系统和库的升级,一些数据类型的定义产生了冲突,这就导致在一些具体的场合下出现了问题。比如在Windows的开发库中,DWORD_PTR和DWORD已经成为了同一类型,但这种变化,可能会导致老的代码的无法正常运行。
2、落后的工具
比如在一些64位的数据库系统中,将指针存储到了int32类型的数据中,这样的结果是什么?很难想象。支持不同平台的静态代码分析器,可能会因为具体的编译及标准不同导致分析结果的不同。最典型的例子就是在VC上可以编译的代码在Linux GCC无法编译。同样,64位平台的发展,也使得早期的很多工具都已经不再完美,需要不断的进行迭代升级,但实际上,这种想法是相当虚妄的。除了某些大公司支持的工具和特别流行的工具外,相当多的工具仍然处于这种不完美的状态。
之所以大多数人对此不敏感,主要的原因在于“应用为主”,而且是上层的应用。这就导致大多数人甚至大多数开发者,对64的敏感性并不够。举一个简单的例子,大多的开发者,其实对内存的要求并不高,几百兆基本都能解决大多数的开发任务,而对于Java等更高级的语言,由于内存管理已经脱离开开发者的掌控,最易于与64位系统直接打交道的方式已经没有了。
放眼全世界,真正与系统底层进行交互,甚至以之为工作的开发者,少之又少。而这其中又包含了很多与此无关的工作,所以,对于应用方,其实很难直接面对32位系统和64位系统的不同导致的问题。
四、改善和提高
做为应用者,谈改善或提高64位系统的细节,有一些困难,不过也不是没有办法:
1、尽可能的找到最新的相关文档,比如硬件系统的官网
2、尽可能的了解使用工具的兼容性和一些问题,并针对这些问题有目的去避开相关的应用
3、针对平台系统的兼容性测试设计一些更详细更安全的单元测试等
4、针对开发者,要有目的的明白开发场景与系统位数的相关性和具体的内容并据此展开分析和编码
五、总结
对大多数开发者来说,这种警惕性可以有,但并不迫切。如果真得有机会搞到底层或硬件相关,再深入的学习和分析才是正解。但仍然在开发中要保持对不同位数系统的敏感,这才能避开系统引入的各种雷区。