将“任何 CPU/首选 32 位”设为 VS 中的默认构建设置背后的基本原理

2023-12-20

假设在 x64 Windows 机器上使用最新版本的 Visual Studio 和 C# 并分配大量数据。

果然,当使用默认构建设置进行编译时(如下图所示为 VS 2019 Preview 2.1),当进程达到 4 GB 时,您将耗尽用户虚拟地址空间。这是可以预料的,并讨论原因here https://stackoverflow.com/questions/54543938/memory-allocation-pattern-on-anycpu-platform-target.

分配本身可以通过创建数百个简单数组来完成,每个数组包含数百万个int元素。

我想了解的是为什么Any CPU/Prefer 32-bit被选为默认构建选项。我还注意到 VS 2015 也具有相同的默认设置,并且很可能自 VS 11 以来发布的每个版本都有相同的默认设置,如上所述here http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/.

通常问的问题是“什么是 AnyCPU...?”并且已经被多次回答(1 https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean 2 https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does 3 https://stackoverflow.com/questions/7508965/what-does-the-prefer-32-bit-compiler-flag-mean-for-visual-studio-c-vb 4 https://stackoverflow.com/questions/13149905/any-cpu-prefer-32-bit/13150845 5 https://stackoverflow.com/questions/5229768/c-sharp-compiling-for-32-64-bit-or-for-any-cpu),简单介绍一下定位的优点x86 / x64 / Any CPU + Prefer 32-bit。但我还没有找到明确的答案Any CPU + Prefer 32-bit选择为 VS 中的默认设置。

详细了解默认情况下反对构建 x64 的原因:

  • The x64 process will use more memory: for the simple example described above (arrays of arrays of int) this shouldn't really be the case. Sure, the reference to the array itself is going to be double (8 bytes instead of 4), but that's about it. As per the "Windows Internals" book https://blogs.msdn.microsoft.com/microsoft_press/2017/05/09/new-book-windows-internals-seventh-edition-part-1/ (Memory Management chapter), the PFN entries in the page table structures themselves are 64 bits wide on both x86 and x64 architectures, it's only that there are 3 (for x86) vs 4 (for x64) of levels of tables for resolving the virtual addresses to physical ones. As for the data referenced, it's the same size (4 bytes per int value). So allocating 20 arrays of 10 million int will roughly translate to 800 MB used for both architectures on the managed heap. Actually, the overall committed size on the x64 version of the simple example just described was about the same as the x86 one when tested (comparison follows, x64 on top, x86 below; and ignoring the 4 GB chunk that's simply in a reserved state for the x64 version). Interestingly enough, while running the 32 bit process on x64, each thread within the process will end up with 2 stacks, a 32-bit wow64 one and a 64-bit one, thus resulting in a higher memory consumption from the perspective of the stack. enter image description here
  • 跨平台可移植性:答案here https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean/2124096#2124096(小心,这是之前Prefer 32-bit选项被发明)提供了一个链接女士推荐 https://learn.microsoft.com/en-us/windows/uwp/packaging/device-architecture#x86(文章截至 2017 年撰写本文时更新)。引用的文章还显示了兼容性矩阵,但这仅适用于 UWP。特别是关于 ARM 架构作为使用构建的输出的开箱即用目​​标AnyCPU/Prefer 32-bit,这是由一个漂亮的表格支持的这个答案 https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean/41766077#41766077. 本文 http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/引用也颇多,展示了.NET 4.5带来的变化以及对ARM的影响。
  • 与现有 32 位应用程序不兼容:有人评论here https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does/12066861#12066861Office 是一个问题,因为它通常安装为 32 位。不过没有太多进一步的信息。
  • Loaded assemblies: A BadImageFormatException is thrown when trying to load an x86 assembly inside a x64 process or the other way around. However, within the comments to this comment https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does/12066861#12066861 it's stated that an assembly compiled with Any CPU/Prefer 32-bit can be loaded in a 64-bit process. I haven't been able to find an official article supporting this though later edit: It can be loaded just fine; I've detailed this and all possible tests for assembly loading here https://mihai-albert.com/2019/03/10/net-assembly-cross-bitness-loading/

最后还是默认的Any CPU/Prefer 32-bit设置很可能是一种权衡,并且以某种方式牺牲了大(> 4 GB)内存访问以换取其他被认为更重要的东西。

不过,Win10 上的 x64 进程用户模式虚拟地址空间的限制是 128 TB,并且 4 GB 物理 RAM 是当今入门级笔记本电脑的标配,因此可能会失去所有额外 RAM 的优势(对于Windows 版本有here https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-limits-for-windows-releases).


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将“任何 CPU/首选 32 位”设为 VS 中的默认构建设置背后的基本原理 的相关文章

  • std::bind2nd 和 std::bind 与二维数组和结构数组

    我知道 C 有 lambda 并且 std bind1st std bind2nd 和 std bind 已弃用 然而 从C 的基础开始 我们可以更好地理解新特性 所以 我从这个非常简单的代码开始 使用int 数组s 第一个例子 与std
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • 尽管浮点数相同,但它们并不相等? [复制]

    这个问题在这里已经有答案了 下面的程序输出This No is not same 当两个数字相同时为什么会这样做 void main float f 2 7 if f 2 7 printf This No is same else prin
  • 如何将 Visual-Studio 2010 切换到 c++11

    我是 c 编程新手 我想尝试 c 11 新功能 那么我要问的是如何切换 Visual studio 2010 才能编译 c 11 源代码 你可以参考这个表 VC10 中的 C 0x 核心语言功能 表格 http blogs msdn com
  • 应用新设置时如何防止 GraphicsDevice 被丢弃?

    我的游戏窗口允许手动调整大小 这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小 游戏还利用了RenderTarget2D rt2d 在主 Draw 方法中设置主渲染目标 GraphicsDevice SetRenderTarge
  • C#生成的csv文件通过电子邮件发送嵌入到Lotus Note中电子邮件的底部

    我遇到了一个奇怪的问题 即使用 NET SmtpClient 通过电子邮件发送的 CSV 附件出现在电子邮件底部 而不是 Lotus Note 中的附件 我只是不知道如何解决这个问题 而且我无法访问客户端计算机 这使得调试非常困难 我可以采
  • 多个线程访问一个变量

    我在正在读的一本教科书中发现了这个问题 下面也给出了解决方案 我无法理解最小值怎么可能是 2 为什么一个线程不能读取 0 而所有其他线程都执行并写入 1 而无论是1还是2 最后写入的线程仍然必须完成自己的循环 int n 0 int mai
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • Web 文本编辑器中的 RTF 格式

    网络上是否有支持 RTF 格式文档输入的文本编辑器 我知道这对 webdev 来说有点奇怪 但我需要从数据库中读取 RTF 文档 并在基于 Web 的文本编辑器中对其进行编辑 然后将其存储回 RTF 中 在我在转换工具上投入太多资金之前 我
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 禁用实体框架的默认值生成(Code First)

    我数据库中有一个列不能为空 我想将其设置为默认值在数据库中 问题是实体框架似乎自己创建了一个默认值 例如 int gt 0 并且完全忽略了数据库中的默认值约束 有没有办法禁用实体框架的默认值 我发现您可以使用以下属性来装饰您的字段 Data
  • 检测笔记本电脑盖子的关闭和打开

    是否可以检测笔记本电脑的盖子何时打开或关闭 从我读到的内容来看 这是不可能的 但 SO 之前已经帮助我完成了不可能的任务 我发现唯一可能朝着正确方向的事情是关于报告电源按钮所需的 IOCTL 的 MSDN 博客文章 https learn
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 删除数组时出现访问冲突异常

    删除分配的内存时 出现 访问冲突读取位置 异常 如下所示 我有一个针对 Visual Studio 2010 工具集 v100 C 编译器编译的本机 dll 我有一个针对它的托管 dll 包装器 它是针对工具集 v90 编译的 因为我想以
  • XCode std::thread C++

    对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • Web API 2.0 使用 pascalcase 模型接收驼峰式命名的 JSON 数据

    我正在尝试对我的 Web API 进行 PUT 调用 我在 WebApiConfig cs 中设置了以下内容 以处理以驼峰形式将数据发送回我的 Web 项目 config Formatters JsonFormatter Serialize

随机推荐