【问题标题】:Which standard C++ features can be used for querying machine/OS architecture?哪些标准 C++ 特性可用于查询机器/操作系统架构?
【发布时间】:2014-08-28 08:09:02
【问题描述】:

用于查询运行程序的硬件或操作系统功能属性的标准 C++ 功能和实用程序有哪些?
例如,std::thread::hardware_concurrency() 为您提供机器支持的线程数。
但是如何检测计算机有多少 RAM,或者进程正在使用多少 RAM,或者在某个目录中有多少磁盘空间可用于写入,或者有多少 L2 缓存可用?

我希望通过 () 标准获得答案,但TR2 或 建议也很好。

【问题讨论】:

  • 标准库中没有这样的东西。我不确定拥有它是否有意义,因为它是特定于平台的东西 - 你怎么知道你的硬件甚至 东西,如 RAM、磁盘空间、目录或 L2 缓存?因此,您应该使用平台的 API 或提供跨平台包装器的第三方库。图书馆推荐请求在这里是题外话,所以你最好提出一个更具体的问题。
  • @JBentley:祝你好运在没有 RAM 的硬件上运行 C++ 程序!
  • @Close-Voters: 同样,不需要外部库或资源!我已经解决了这个问题。 @Nick-Thompson:OP 可能会添加评论或编辑问题,首先不同意我对问题的解释。
  • @Gabe mmap 和全息记忆?
  • @Gabe:RAM 只是意味着“随机存取存储器”。原则上或实践中没有任何东西可以阻止 C++ 的实现仅使用顺序访问的内存。也许有问题的 C++ 程序正在运行磁带驱动器

标签: c++ c++14 boost c++ c++11 computer-architecture c++14


【解决方案1】:

您如何检测计算机有多少 RAM,或者进程正在使用多少 RAM,或者某个目录中有多少磁盘空间可用于写入,或者有多少 L2 缓存可用?

你没有。正是这些都不是 C++ 语言的权限,它描述了一个抽象机器。

它告诉你可用内核数量的唯一原因是因为否则它的多线程模型将接近无用,即使这样它也以抽象的方式这样做(“硬件并发”不是“物理 CPU 的数量在您的台式电脑中”)。

【讨论】:

    【解决方案2】:

    std::thread::hardware_concurrency() 为您提供机器支持的线程数...”

    不,不是。准确地说是 (citing from here)

    std::thread::hardware_concurrency() ... 返回实现支持的并发线程数。该值应仅被视为一个提示。 ...
    ...如果该值定义不明确或不可计算,则返回​0

    这样做的好处是让您知道有多少 CPU 内核可用于线程的真正并行执行(请参阅@Lightness Races in Orbit's answer here)。
    您仍然可以拥有任意数量的线程实例,直到获取失败为止。


    “你如何检测计算机有多少 RAM,或者进程正在使用多少 RAM,......”

    所有这些功能(如可用 RAM 等)都高度依赖于机器/操作系统,并且无法使用标准 c++ 函数或类进行查询(至少我不知道)。

    "...或者某个目录中有多少磁盘空间可以写入,..."

    C++ 标准库也没有像文件系统目录这样的概念...

    “...或者有多少二级缓存可用”

    ...甚至更少关于这种高度 MCU 特定特征的概念1

    C++ 使用完全抽象的、机器架构和操作系统无关的世界观。

    1) 感谢上帝、Bjarne 和 c++ 标准委员会,否则我会遇到严重的问题,为我面临的各种目标编写中途可移植代码。如果它失败了,并且不能从我这边证明是违反标准的错误,那很可能是实际编译器实现的错误。这至少会阻碍我的编码人员松手,因为他们进行了不必要的和晦涩的微优化尝试:-D。


    以上都说:

    <cstddef>, <limits> and <type_traits> IMHO 支持的最接近的方法是使用当前标准要求一些机器架构的基本特征和功能。

    尽管最新的标准定义采用了一些常见的“最新技术”技术和抽象(例如std::threadstd::chronofilesystem experimental library)。

    【讨论】:

    • bad_alloc 并不表示 RAM 已用完
    • @BenVoigt 由于这引起了如此多的关注,我想改进。您能否建议如何更准确地表达这一点,或者如果您愿意,可以进行编辑。
    • bad_alloc 如果虚拟地址空间用尽,则会发生。这可能发生在 RAM 耗尽之前(例如,在 64 位操作系统上运行 32 位或 x32 代码,系统中的 RAM 大于 4GB)。并且 RAM 耗尽可能会发生而不会耗尽虚拟地址空间,这通常会导致使用交换文件或交换分区。如果您也用完交换,则行为取决于是否启用了过量使用。
    • @BenVoigt 好的,非常感谢您的澄清。当然,这个细节很好地区分了 'address space''RAM' 的含义。 “Out of (virtual) memory” 会比 POV 中的 “RAM is exhausted” 更好地描述这一点吗?
    • 我不会将其描述为“虚拟内存不足”,尤其是在有关系统状态的问题的上下文中。如果一个进程耗尽了它的虚拟地址空间,这意味着它已经达到了可以分配给该进程的虚拟内存的限制(超出),但没有说明系统是否还有剩余的虚拟内存。哦,我猜bad_alloc 也可能表示达到了ulimit(或类似的)配置的限制,即使地址空间支持更高的限制。仍然没有说明整体系统内存。
    【解决方案3】:

    正如其他人所指出的,用于获取系统此类属性的函数通常是特定于平台的。 STL 和 boost 不提供独立于平台的包装器,因此您必须依赖其他第三方库。

    我过去成功使用过SIGAR

    Sigar API 为采集系统提供了一个可移植的接口 信息如:

    • 系统内存、交换、CPU、平均负载、正常运行时间、登录次数
    • 每个进程的内存、cpu、凭据信息、状态、参数、环境、打开的文件
    • 文件系统检测和指标
    • 网络接口检测、配置信息和指标
    • TCP 和 UDP 连接表
    • 网络路由表

    附带说明一下,Boost Filesystem 实际上确实提供了boost::filesystem::space 来查询“在某个目录中有多少磁盘空间可用于写入”。

    【讨论】:

    • 抱歉,我不得不对此投反对票。我只是想写一个评论,为什么把这个问题作为 OT 来结束,因为不应该应用外部引用和库。如果您对此有任何答案,它应该非常接近下一个c++1y 标准的路径和概念。您的提案看起来与 IIRC 的任何标准概念相去甚远。
    • 顺便说一句,那里有很多这样的框架和库(检查PocoPlatinum C++ 等),但它们几乎都没有成为讨论的'成为未来标准' 完全没有。
    【解决方案4】:

    确定可用 RAM 或硬盘空间的数量是操作系统级别的功能。因为有许多不同的策略可用于解决这些问题,所以没有独立于平台的方式来获取这些信息。您正在开发的任何操作系统的 API 都应该提供确定这些值的功能。

    例如,windows API 似乎提供了这个功能: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366589%28v=vs.85%29.aspx 这可以帮助您确定有多少物理/虚拟内存可用。

    确定可用的缓存空间量是另一回事,以下答案可能会对您有所帮助: https://stackoverflow.com/a/12838695/3798126

    【讨论】:

      猜你喜欢
      • 2015-06-16
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2016-04-11
      • 2021-05-19
      • 2018-07-13
      相关资源
      最近更新 更多