- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
编辑:我用我的基准测试的细节更新了我的问题
出于基准测试目的,我尝试在运行于两个 Intel Xeon 56xx(“Westmere”)处理器之上的 Linux 3.13 系统中设置 1GB 页面。为此,我修改了引导参数以添加对 1GB 页面(10 页)的支持。这些引导参数仅包含 1GB 页面而不是 2MB 页面。运行 hugeadm --pool-list
导致:
Size Minimum Current Maximum Default
1073741824 10 10 10 *
我的内核启动参数被考虑在内。在我的基准测试中,我分配了 1GiB 的内存,我希望使用 1GiB 的大页面来支持它:
#define PROTECTION (PROT_READ | PROT_WRITE)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
uint64_t size = 1UL*1024*1024*1024;
memory = mmap(0, size, PROTECTION, FLAGS, 0, 0);
if (memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
sleep(200)
在长凳休眠时查看/proc/meminfo
(上面的sleep
调用),我们可以看到已经分配了一个大页面:
AnonHugePages: 4096 kB
HugePages_Total: 10
HugePages_Free: 9
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
注意:我在运行 bench 之前禁用了 THP(通过 /sys
文件系统),所以我猜测 AnonHugePages
报告的字段/proc/meminfo
表示 THP 在停止之前分配的大页面。
此时我们可以认为一切都很好,但不幸的是,我的工作台让我认为使用了许多 2MiB 页面而不是一个 1GiB 页面。解释如下:
该工作台通过指针追逐随机访问分配的内存:第一步填充内存以启用指针追逐(每个单元格指向另一个单元格),第二步工作台使用
pointer = *pointer;
使用 perf_event_open
系统调用,我仅计算基准第二步的数据 TLB 读取未命中数。当分配的内存大小为 64MiB 时,我计算了一个非常小的数字,即我 6400000 次内存访问的 0.01%,数据 TLB 读取未命中。所有访问都保存在 TLB 中。也就是说,TLB中可以保留64MiB的内存。一旦分配的内存大小大于 64 MiB,我就会看到数据 tlb 读取未命中。对于等于 128 MiB 的内存大小,我的 6400000 次内存访问中有 50% 在 TLB 中丢失。 64MiB 似乎是可以放入 TLB 的大小,64MiB = 32 个条目(如下所述)* 2MiB 页。我得出结论,我使用的不是 1GiB 页面,而是 2MiB 页面。
你能看出这种行为的任何解释吗?
此外,cpuid
工具报告了以下有关我系统上的 tlb 的信息:
cache and TLB information (2):
0x5a: data TLB: 2M/4M pages, 4-way, 32 entries
0x03: data TLB: 4K pages, 4-way, 64 entries
0x55: instruction TLB: 2M/4M pages, fully, 7 entries
0xb0: instruction TLB: 4K, 4-way, 128 entries
0xca: L2 TLB: 4K, 4-way, 512 entries
L1 TLB/cache information: 2M/4M pages & L1 TLB (0x80000005/eax):
L1 TLB/cache information: 4K pages & L1 TLB (0x80000005/ebx):
L2 TLB/cache information: 2M/4M pages & L2 TLB (0x80000006/eax):
L2 TLB/cache information: 4K pages & L2 TLB (0x80000006/ebx):
如您所见,没有关于 1GiB 页面的信息。 TLB 中可以缓存多少这样的页面?
最佳答案
您(特别是您的处理器)在这种情况下无法从 1GB 页面中获益,但您的代码是正确的,无需在可以的系统上进行修改。
我按照这些步骤尝试重现您的问题。
My System: Intel Core i7-4700MQ, 32GB RAM 1600MHz, Chipset H87
svn co https://github.com/ManuelSelva/c4fun.git
cd c4fun.git/trunk
制作
。发现需要一些依赖项。安装了它们。构建失败,但是 mem_load
确实构建并链接了,所以没有进一步追求其余部分。
重新启动系统,在 GRUB 时将以下内容附加到启动参数:
hugepagesz=1G hugepages=10 default_hugepagesz=1G
保留 10 个 1GB 页面。
cd c4fun.git/trunk/mem_load
使用 memload
在随机访问模式模式下运行多个测试并将其固定到核心 3,核心 3 不是 0(引导处理器)。
./mem_load -a rand -c 3 -m 1073741824 -i 1048576
这导致几乎没有 TLB 未命中。
./mem_load -a rand -c 3 -m 10737418240 -i 1048576
这导致大约 60% 的 TLB 未命中。凭直觉我做到了
./mem_load -a rand -c 3 -m 4294967296 -i 1048576
这导致几乎没有 TLB 未命中。凭直觉我做到了
./mem_load -a rand -c 3 -m 5368709120 -i 1048576
这导致大约 20% 的 TLB 未命中。
此时我下载了 cpuid
实用程序。它给了我 cpuid -1 | grep -i tlb
:
cache and TLB information (2):
0x63: data TLB: 1G pages, 4-way, 4 entries
0x03: data TLB: 4K pages, 4-way, 64 entries
0x76: instruction TLB: 2M/4M pages, fully, 8 entries
0xb5: instruction TLB: 4K, 8-way, 64 entries
0xc1: L2 TLB: 4K/2M pages, 8-way, 1024 entries
L1 TLB/cache information: 2M/4M pages & L1 TLB (0x80000005/eax):
L1 TLB/cache information: 4K pages & L1 TLB (0x80000005/ebx):
L2 TLB/cache information: 2M/4M pages & L2 TLB (0x80000006/eax):
L2 TLB/cache information: 4K pages & L2 TLB (0x80000006/ebx):
如您所见,我的 TLB 有 4 个条目用于 1GB 页面。这很好地解释了我的结果:对于 1GB 和 4GB arena,TLB 的 4 个插槽完全足以满足所有访问。对于 5GB arenas 和随机访问模式模式,5 个页面中的 4 个只能通过 TLB 映射,因此将指针追逐到剩余页面将导致未命中。将指针追入未映射页面的概率是 1/5,因此我们预计未命中率为 1/5 = 20%,我们得到了。对于 10GB,有 4/10 个页面被映射,6/10 没有被映射,因此未命中率为 6/10=60%,我们知道了。
所以你的代码至少在我的系统上不需要修改就可以工作。那么您的代码似乎没有问题。
然后我在 CPU-World 上做了一些研究,虽然不是所有的 CPU 都列出了 TLB 几何数据,但有些是。我看到的唯一与您的 cpuid 打印输出完全匹配的(可能还有更多)是 Xeon Westmere-EP X5650 ; CPU-World 没有明确表示数据 TLB0 具有 1GB 页面的条目,但确实表示处理器具有“1 GB 大页面支持”。
然后我做了更多的研究并最终确定了它。 RealWorldTech 的一位作者在对 Sandy Bridge 的内存子系统的讨论中做了一个(诚然,我必须为此找到来源)临时评论。上面写着 as follows :
After address generation, uops will access the DTLB to translate from a virtual to a physical address, in parallel with the start of the cache access. The DTLB was mostly kept the same, but the support for 1GB pages has improved. Previously, Westmere added support for 1GB pages, but fragmented 1GB pages into many 2MB pages since the TLB did not have any 1GB page entries. Sandy Bridge adds 4 dedicated entries for 1GB pages in the DTLB.
(强调)
无论“CPU 支持 1GB 页面” 代表什么模糊概念,Intel 认为它并不暗示“TLB 支持 1GB 页面条目”。恐怕您将无法在 Intel Westmere 处理器上使用 1GB 页面来减少 TLB 未命中数。
那,或者英特尔通过区分大页面(在 TLB 中)和大页面来蒙蔽我们。
关于c - 如何在 Linux 上使用 Intel Westmere 1GB 页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27951778/
#include typedef std::vector vc; typedef std::vector vvc; vvc f() { const int N = (1 不把它还给操作系统。 因
我正在尝试训练 Dlib's train_shape_predictor_ex.cpp与 Halen数据集。我在 Release模式 中使用 Visual Studio 将代码编译为 64 位平台 作
当我试图解决this 时想到了这个问题。问题。 我有一个容量为 120 GB 的硬盘,其中 100 GB 被一个巨大的文件占用。所以 20 GB 仍然是免费的。 我的问题是,我们如何将这个巨大的文件拆
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Can you allocate a very large single chunk of memory (
我有一台运行 Linux (3.19.5-200.fc21.x86_64) 的 128 GB RAM 的计算机。但是,我不能在单个进程中分配超过 ~30 GB 的 RAM。除此之外,malloc 失败
我需要为 808704000 个 float 分配内存,大约是 3085 MB。我的电脑有 32 GB 内存,运行 64 位 Linux (CentOS 6.6)。每次我尝试分配内存时,malloc
很抱歉这个愚蠢的问题,但是当reading about 32 bits limitation ,我发现由于 Memory-Mapped 方法,MongoDB 不能存储超过 2 GB,但是: 2^32
假设我们有一个 32 位地址,那么每一位可以是 1 或 0。 所以组合总数等于2^32。 所以我们可以表示 2^32 个地址(没有单位)。 但为什么人们说 32 位地址可以表示 2^32 字节地址(为
好吧,这个问题确实是一个挑战! 背景 我正在从事一个涉及比正常数字更大的基于算术的项目。我是新手,我打算使用 4 GB 文件大小的最坏情况(我什至希望将其扩展到 5GB 上限,因为我之前看到文件大小大
我在文件系统上有大约 12 个大小为 1 GB 到 10 GB 的存储库,我需要为所有这些存储库设置自动备份(我们的旧备份脚本在计算机出现故障时丢失了) XP 64 位机器。 看完this quest
我尝试调整 Linux VM 上的操作系统磁盘大小,该 VM 通常由 azure 自动创建。我无法创建自定义操作系统磁盘 - 请告知我该怎么做? enter image description her
我在 .NET 中遇到了一个问题,我的数组受到我拥有的 RAM 数量的限制,并且我需要可以容纳至少 40 GB 字节的数组。我正在考虑使用硬盘驱动器作为虚拟数组的想法不在乎它是否慢。 我正在研究这个想
我尝试调整 Linux VM 上的操作系统磁盘大小,该 VM 通常由 azure 自动创建。我无法创建自定义操作系统磁盘 - 请告知我该怎么做? enter image description her
我的目标是看看当使用比物理 GPU 内存所能容纳的更多纹理数据时会发生什么。我的第一次尝试是加载多达 40 个 DDS 纹理,导致内存占用比 GPU 内存高得多。但是,我的场景在 9500 GT 上仍
Windows 上的 JDK 最多需要 2 GB 左右的 RAM。即使我们为 JDK 分配更多 RAM;它不接受它。如果我需要在 Windows 上运行需要 8 GB RAM 的进程;我怎样才能实现它
我有一个程序需要分配2个15亿长度的整数数组。这是一个编码挑战( https://projecteuler.net/problem=282 ),并且没有办法使用如此大的数组(如果有,请不要告诉我;我应
假设我有一个 32 位内核。 4 Gb RAM,10 Gb 交换分区。 我有一个在无限循环中有 malloc 的进程。因此,最终系统的 OOM 将终止该进程。这里有两个论点。 参数 1:因为它是 32
我有一个可以大于 4GB 的文件。我正在使用 linux split 命令按行拆分它(这是要求)。但是拆分原始文件后,我希望拆分文件的大小始终小于 2GB。原始文件大小可能在 3-5 GB 之间。我想
我有一台带有 32GB RAM 的 Mac 服务器(雪豹)。当我尝试在 Perl (v 5.10.0) 中分配超过 1.1GB 的 RAM 时,出现内存不足错误。这是我使用的脚本: #!/usr/bi
我们正在尝试运行.NET 4 Web应用程序(在8 GB,8核心Windows 2008 R2 64位Webedition服务器上),该应用程序使用Spire.doc创建Word mailmerge文
我是一名优秀的程序员,十分优秀!