草庐IT

64 位机器中的 C++ int 与 long long

coder 2023-06-01 原文

我的电脑有 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)

在编译器和汇编器之间,会生成正确的代码,以便正确处理 32 位值。

其次,当我们谈论内存开销和性能时,我们应该更加具体。现代内存系统由一个磁盘、主内存 (RAM) 和通常两个或三个缓存(例如 L3、L2 和 L1)组成。可以在磁盘上寻址的最小数据量称为页,页大小通常为 4096 字节(尽管并非必须如此)。然后,内存中可以寻址的最小数据量称为缓存线,通常比 32 或 64 位大得多。在我的计算机上,缓存行大小为 64 字节。处理器是数据在字级及以下进行实际传输和寻址的唯一地方。

因此,如果您想更改驻留在磁盘上的文件中的一个 64 位字,那么在我的计算机上,这实际上需要您将磁盘中的 4096 字节加载到内存中,然后将内存中的 64 字节加载到 L3、L2 , 和 L1 缓存,然后处理器从 L1 缓存中获取单个 64 位字。

结果是字长对内存带宽没有任何意义。但是,您可以在可以打包 8 个 64 位整数的相同空间中放置 16 个 32 位整数。或者您甚至可以在同一空间中容纳 32 个 16 位值或 64 个 8 位值。如果您的程序使用许多不同的数据值,您可以通过使用所需的最小数据类型来显着提高性能。

关于64 位机器中的 C++ int 与 long long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39779880/

有关64 位机器中的 C++ int 与 long long的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  8. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

随机推荐