Use*_*rRR 17 c++ memory performance cpu-word 32bit-64bit
我的计算机有64位处理器,并且当我寻找sizeof(int)
,sizeof(long)
以及sizeof(long long)
,事实证明,INT和长为32位,和长长为64位.我研究了原因,看来普遍的假设是说C++ 中的int符合机器的字大小是错误的.据我所知,编译器需要定义大小,我的是Mingw-w64.我研究的原因是理解如果小于字大小的类型的使用有利于速度(例如,短与int)或它是否具有负面影响.在32位系统中,一种流行的观点是:由于字大小为int,short将被转换为int,这将导致额外的位移等,从而导致更差的性能.反对意见是缓存级别会有好处(我没有深入研究),使用short会对虚拟内存经济有用.所以,除了这种困境之间的混淆之外,我还面临着另一个问题.我的系统是64位,如果我使用int或short并不重要,它仍然会小于字大小,我开始认为使用64位长的长度不是很有效,因为它是在系统设计的级别.另外我读到还有另一个约束,即OS的库(ILP64,LP64),它定义了类型大小.在ILP64中,与LP64相比,默认int为64位,如果我使用支持ILP64的操作系统,它会加速程序吗?一旦我开始询问我应该使用哪种类型来加速我的C++程序,我就面临更深层次的主题,其中我没有专业知识,而且一些解释似乎相互矛盾.你能解释一下:
1)如果最佳做法是在x64中使用long long来实现最高性能,即使对于1-4字节数据也是如此?
2)使用小于字大小的类型(内存胜利与附加操作)的权衡
3)word和int size是64位的x64计算机是否有可能通过使用所谓的向后兼容性使用16位字大小来处理短路?或者它必须将16位文件放入64位文件中,并且可以完成的事实将系统定义为向后兼容.
4)我们可以强制编译器使int 64位?
5)如何将ILP64整合到使用LP64的PC中?
6)使用适用于其他编译器,操作系统和体系结构(32位处理器)的上述问题的代码可能存在哪些问题?
Dav*_*vid 33
1)如果最佳做法是在x64中使用long long来实现最高性能,即使对于1-4字节数据也是如此?
不 - 它实际上可能会使你的表现更糟.例如,如果你使用64位整数,你可以用32位整数,那么你只需要在处理器和内存之间发送的数据量增加一倍,内存就会慢几个数量级.所有缓存和内存总线的速度都会快两倍.
2)使用小于字大小的类型(内存胜利与附加操作)的权衡
通常,现代机器中性能的主要驱动因素是需要存储多少数据才能运行程序.一旦程序的工作集大小超过了寄存器,L1缓存,L2缓存,L3缓存和RAM的容量,您将看到重要的性能悬崖.
此外,如果您的编译器足够智能以找出如何使用处理器的向量指令(也称为SSE指令),则使用较小的数据类型可能是一个胜利.现代矢量处理单元足够聪明,可以将8个16位短整数填充到与两个64位长整数相同的空间中,因此一次可以执行四次操作.
3)word和int size是64位的x64计算机是否有可能通过使用所谓的向后兼容性使用16位字大小来处理短路?或者它必须将16位文件放入64位文件中,并且可以完成的事实将系统定义为向后兼容.
我不确定你在这里问什么.通常,64位计算机能够执行32位和16位可执行文件,因为早期的可执行文件使用64位计算机潜在的子集.
硬件指令集通常是向后兼容的,这意味着处理器设计者倾向于添加功能,但很少删除功能.
4)我们可以强制编译器使int 64位?
所有编译器都有相当标准的扩展,允许您使用固定位大小的数据.例如,头文件stdint.h
声明类型,例如int64_t
,uint64_t
等
5)如何将ILP64整合到使用LP64的PC中?
https://software.intel.com/en-us/node/528682
6)使用适用于其他编译器,操作系统和体系结构(32位处理器)的上述问题的代码可能存在哪些问题?
通常,编译器和系统足够聪明,可以弄清楚如何在任何给定系统上执行代码.但是,32位处理器将不得不做额外的工作来操作64位数据.换句话说,正确性不应该是一个问题,但性能将是.
但通常的情况是,如果性能对您来说非常关键,那么无论如何您都需要针对特定的架构和平台进行编程.
澄清请求:非常感谢!我想澄清问题:1.你说这对记忆有害.让我们举一个32位int的例子.当你把它发送到内存,因为它是64位系统,对于一个所需的整数0xee ee ee,当我们发送它不会变成0xee ee ee ee + 32个其他位?当字长为64位时,处理器如何发送32位?32位是所需的值,但不会与32个未使用的位组合并以这种方式发送?如果我的假设是正确的,那么记忆就没有区别了.
这里有两件事要讨论.
首先,您讨论的情况不会发生.处理器不需要将32位值"提升"为64位值,以便适当地使用它.这是因为现代处理器具有不同的访问模式,能够适当地处理不同大小的数据.
例如,64位Intel处理器具有名为RAX的64位寄存器.但是,通过将其称为EAX,甚至在16位和8位模式下,可以在32位模式下使用该相同的寄存器.我从这里偷了一张图:
x86_64寄存器rax/eax/ax/al覆盖完整寄存器内容
1122334455667788
================ rax (64 bits)
======== eax (32 bits)
==== ax (16 bits)
== ah (8 bits)
== al (8 bits)
Run Code Online (Sandbox Code Playgroud)
在编译器和汇编器之间,生成正确的代码,以便正确处理32位值.
其次,当我们谈论内存开销和性能时,我们应该更具体.现代存储器系统由磁盘,主存储器(RAM)和通常两个或三个高速缓存(例如L3,L2和L1)组成.可以在磁盘上寻址的最小数据量称为页面,页面大小通常为4096字节(尽管它们不必是).然后,可在内存中寻址的最小数据量称为缓存行,通常远大于32或64位.在我的计算机上,缓存行大小为64字节.处理器是唯一一个在字级及以下实际传输和寻址数据的地方.
因此,如果要更改驻留在磁盘上的文件中的一个64位字,那么,在我的计算机上,这实际上要求您将4096个字节从磁盘加载到内存中,然后从内存加载64个字节到L3,L2和L1缓存,然后处理器从L1缓存中获取一个64位字.
结果是字大小对内存带宽毫无意义.但是,您可以在同一空间中容纳16个32位整数,这些空间可以打包8个64位整数.或者您甚至可以在同一空间中容纳32个16位值或64个8位值.如果您的程序使用大量不同的数据值,则可以使用所需的最小数据类型来显着提高性能.
归档时间: |
|
查看次数: |
7460 次 |
最近记录: |