- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我的电脑有 64 位处理器,当我寻找 sizeof(int)
时, sizeof(long)
, 和 sizeof(long long)
,原来是 国际和 长是 32 位,和 长长是 64 位。我研究了原因,似乎流行的假设告诉 国际在 C++ 中适合机器的字大小是错误的。据我了解,由编译器来定义大小,我的是 Mingw-w64。我研究的原因是了解如果使用小于字大小的类型有利于速度(例如, short vs int )或者是否有负面影响。在 32 位系统中,一种流行的观点是:由于字长为 。国际 , 短将转换为 国际它会导致额外的位移等,从而导致性能下降。反对意见是缓存级别会有好处(我没有深入研究),使用短对虚拟内存经济很有用。所以,除了这种两难的困惑之外,我还面临着另一个问题。我的系统是64位的,用也没关系国际或 短 ,它仍然会小于字的大小,我开始想使用 64 位会不会很有效 长长因为它处于系统设计的级别。我还读到还有另一个约束,它是定义类型大小的操作系统的库(ILP64,LP64)。在 ILP64 中默认 国际与 LP64 相比是 64 位,如果我使用支持 ILP64 的操作系统,它会加速程序吗?一旦我开始问我应该使用哪种类型来加速我的 C++ 程序,我面临更深层次的主题,我没有专业知识,有些解释似乎相互矛盾。你能解释一下吗:
1) 如果最好使用 长长在 x64 中即使对于 1-4 字节数据也能实现最高性能?
2)权衡使用小于字大小的类型(内存获胜与附加操作)
3) 字和整数大小为 64 位的 x64 计算机是否有可能通过使用所谓的向后兼容性来处理短的、使用 16 位字的大小?或者它必须将 16 位文件转换为 64 位文件,并且可以做到这一点的事实将系统定义为向后兼容。
4) 我们可以强制编译器生成吗?国际 64位?
5) 如何将 ILP64 集成到使用 LP64 的 PC 中?
6) 使用适用于其他编译器、操作系统和架构(32 位处理器)的上述问题的代码可能会出现哪些问题?
最佳答案
1) 如果在 x64 中使用 long long 来实现最高性能是最佳实践,即使对于 1-4 字节数据也是如此?
不 - 它实际上可能会使您的表现更糟。例如,如果您使用 64 位整数,而您可以使用 32 位整数,那么您只是将必须在处理器和内存之间发送的数据量增加了一倍,而内存要慢几个数量级。您所有的缓存和内存总线都会以两倍的速度崩溃。
2)权衡使用小于字大小的类型(内存获胜与附加操作)
通常,现代机器性能的主要驱动因素是需要存储多少数据才能运行程序。一旦程序的工作集大小超过寄存器、L1 缓存、L2 缓存、L3 缓存和 RAM 的容量,您将看到显着的性能悬崖。
此外,如果您的编译器足够聪明,可以弄清楚如何使用处理器的 vector 指令(又名 SSE 指令),那么使用较小的数据类型可能会是一个胜利。现代 vector 处理单元足够智能,可以将 8 个 16 位短整数与两个 64 位长整数填充到相同的空间中,因此您可以一次执行四倍的运算。
3) 字和整数大小为 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 ee,当我们发送它时它会不会变成0x ee ee ee ee+其他32位?当字长为 64 位时,处理器如何发送 32 位? 32 位是所需的值,但它不会与 32 位未使用的位组合并以这种方式发送吗?如果我的假设是真的,那么内存没有区别。
这里有两件事要讨论。
首先,你讨论的情况没有发生。处理器不需要将 32 位值“提升”为 64 位值才能正确使用它。这是因为现代处理器具有不同的访问模式,能够适本地处理不同大小的数据。
例如,64 位 Intel 处理器有一个名为 RAX 的 64 位寄存器。但是,通过将其称为 EAX,这个相同的寄存器可以在 32 位模式下使用,甚至可以在 16 位和 8 位模式下使用。我从这里偷了一张图:
x86_64 registers rax/eax/ax/al overwriting full register contents
1122334455667788
================ rax (64 bits)
======== eax (32 bits)
==== ax (16 bits)
== ah (8 bits)
== al (8 bits)
关于64 位机器中的 C++ int 与 long long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39779880/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!