By Minidxer | October 8, 2007
简介
在市场上大多数CPU和操作系统支持64的操作处理。这种模式特别有利于需要运行大量数据的科学和工程应用。主要优势在于可使用巨大的地址空间。程序能够分配两次更多内存,容易维护大型数据库等。并且还有一定的性能优化优势。大多数64位机器运算集中能力处理需要超过4GB的内存。目前版本的BM library没有涉及内存问题,而是关注于表现方面。64位CPU在同一时间运行64位的计算是可以而且必须的功能。
64-bit Safety
可惜如今的很多软件并没有利用64位微处理器的优势,甚至经常不能在64位模式下编译运行。在这种情况下常常运行32位兼容模式。这真是对芯片的一种浪费啊。所以,让我们面对挑战来看一下如果我们用64位CPU替代32位系统出现的不当C编码。
每个时间周期下获得最大工作效率
高性能64位C程序的关键点在于广泛的整数运算处理寄存器。寄存器(Registers)是一种昂贵的计算机内存。64位CPU寄存器是8字节。它通常伴随相应的128位或256位内存通路。我们的目标是有效地利用这些资源。
让我们来看一段C编码的短例。在一块内存中进行与(AND)操作,基于整数位集合块
{
int a1[2048];
int a2[2048];
int a3[2048];
for (int i = 0; i < 2048; ++i)
{
a3[i] = a1[i] & a2[i];
}
}
现在我们能优化以上这段编码为64位模式。(这段编码是长C形并不是有编译器提供)
{
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];
}
}
如你所见,我们并没有改变位集合块的总体大小。但AND的矢量运算只花了两次很少的操作。这减少了架设回路并且等价与用系数2展开回路。缺点在于它是纯64位。用32位系统汇编时由于长度不同而提示错误信息。
进一步的优化可如下所示:
{
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];
}
}
以上代码是32位和稳定的64位以及使用寄存器在64位CPU上工作。如果这样编码写得话,我们要记住指针的位置。如果我们盲目的用整数(int)指针作为64位长指针,有可能产生地址不为8位的情况。对于一些结构来说这将造成总线(BUS)错误及冲突。这一影响发现于Sun Solaris。很可能是32位整数变量(int variable),形成堆将有4位对应地址,那以上的编码就无用了。
位计数(Bits counting )
在位设置运算中最重要的操作就是计算1位的数目。BM使用整数位矢量,这意味着每一个位矢量是由整数列作为一个最小单位组成。BM的默认方法是把每个整数分成4字节然后查找包含位计数的表。使用16位宽表这种能提高该线性方法的效率,代价是生成巨大的列表。巨大的列表很有可能产生额外内存的存取操作,妨碍CPU缓存最后导致性能并没有得到显著提升。
int count(long long b)
{
b = (b & 0×5555555555555555LU) + (b >> 1 & 0×5555555555555555LU);
b = (b & 0×3333333333333333LU) + (b >> 2 & 0×3333333333333333LU);
b = b + (b >> 4) & 0×0F0F0F0F0F0F0F0FLU;
b = b + (b >> 8);
b = b + (b >> 16);
b = b + (b >> 32) & 0×0000007F;
return (int) b;
}
这段代码的灵感来自于Gutman 2000年9月在Dr.Dobb’s 杂志上发表的”Exploiting 64-Bit parallelism 开发64位并行”。实验表明,这段代码将表计数的方法远远的甩在身后。
执行(Implementation )
目前BM 版本使用64位运算优化提高性能。为了转换成你所需要的在制作文件前或进行中头文件预先定义BM640PT宏函数。这一选项使得64位长整形可使用。执行时允许该选项在32位机器上例如Intel x86 CPU编辑运行BM。不用说,这样的操作你很快就会发现不但没有利用优势反而使得性能降低了。
明智得在例如Intel Itanium, MIPS, HP PA-RISC, IBM’s POWER Series, Compaq Alpha, Sun UltraSPARC等64位CPU上使用该选项。
总结
我们已经讲述了几种如何利用64位操作来提高位间运算的性能。由于Intel和AMD扩大了64位处理器的生产线的背景下,转换成64位系统变得特别重要。如果你知道其他能提高改善64位性能的方法,我将会很高兴听到这一消息。