Questions tagged «memory-management»

4
便携式多核/ NUMA内存分配/初始化最佳实践
当在共享内存环境(例如,通过OpenMP,Pthreads或TBB进行线程化)中执行内存带宽受限的计算时,将存在一个难题,即如何确保内存在物理内存之间正确分配,以使每个线程大部分访问内存中的内存。 “本地”内存总线。尽管接口不是可移植的,但是大多数操作系统都有设置线程相似性的方法(例如,pthread_setaffinity_np()在许多POSIX系统,sched_setaffinity()Linux,SetThreadAffinityMask()Windows上)。还有诸如hwloc之类的库,用于确定内存层次结构,但是不幸的是,大多数操作系统尚未提供设置NUMA内存策略的方法。Linux是一个明显的例外,libnuma允许应用程序以页面粒度操作内存策略和页面迁移(自2004年以来一直在主流中使用,因此已广泛使用)。其他操作系统希望用户遵守隐式的“首次触摸”策略。 使用“首次触摸”策略意味着调用者应在首次写入新分配的内存时以他们打算在以后使用的相似性来创建和分发线程。(很少有系统配置为malloc()实际上可以找到页面,它只是承诺在页面实际出现故障时(可能是由不同的线程)找到它们。)这意味着使用分配calloc()或在分配使用之后立即初始化内存memset()是有害的,因为它易于出错将所有内存分配到运行分配线程的核心的内存总线上,从而导致从多个线程访问内存时出现最坏情况的内存带宽。同样适用于new坚持初始化许多新分配的C ++ 运算符(例如std::complex)。关于此环境的一些观察结果: 可以将分配设为“线程集合”,但是现在分配混入了线程模型,这对于可能不得不使用不同线程模型(也许每个都有自己的线程池)与客户端进行交互的库来说是不希望的。 RAII被认为是惯用C ++的重要组成部分,但它似乎对NUMA环境中的内存性能有积极的危害。new可以将布局与通过malloc()或从中分配的例程一起使用libnuma,但这会改变分配过程(我认为这是必要的)。 编辑:我之前有关运算符的声明new不正确,它可以支持多个参数,请参阅Chetan的回复。我相信仍然需要让库或STL容器使用指定的相似性。可能会打包多个字段,并且可能不方便确保例如std::vector在激活正确的上下文管理器的情况下进行重新分配。 每个线程都可以分配并分配其自己的私有内存,但是将它们索引到相邻区域会更加复杂。(考虑一个稀疏的矩阵向量乘积,其中矩阵和向量按行划分;索引x的未拥有部分时,如果x在虚拟内存中不连续,则需要更复杂的数据结构。)ÿ← A xÿ←一种Xy \gets A xXXxXXx 是否认为NUMA分配/初始化的任何解决方案都是惯用的?我是否遗漏了其他关键陷阱? (我并不是说我的C ++示例暗示要强调该语言,但是C ++ 语言编码了一些有关内存管理的决定,而C之类的语言则没有这样做,因此在建议C ++程序员这样做时往往会有更大的阻力情况有所不同。)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.