首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C/C++中页表锁开销的测量

C/C++中页表锁开销的测量
EN

Stack Overflow用户
提问于 2022-03-31 20:49:32
回答 1查看 152关注 0票数 1

Linux内核中页面表的PMD和PTE级别上有两个锁。每次线程/进程分配/映射一个内存时,它都应该持有其中一个锁,以便相应地更新页面表。很明显,随着线程数量的增加,保持锁的竞争也会增加。这可能会降低内存映射吞吐量,因为许多线程持有自旋锁。

我想为任务度量的是这些锁在内存映射吞吐量上的最坏的开销,但我不知道如何度量它。

我尝试在infinite-loop中使用infinite-loop,因为我增加了运行相同循环的线程数。我检查每一组正在运行的线程的/proc/{pid}/maps,以计数映射的内存数。但我不确定这是不是正确的方法。此外,这种方法消耗了大量的内存。

有什么有效的方法来测量这些锁的最坏的开销吗?

EN

回答 1

Stack Overflow用户

发布于 2022-03-31 23:00:17

很多评论都是正确的,但是我想我可能会试着完全的回答。首先,使用malloc不能显式控制页面映射,因为注释说stdlib的malloc部分实际上将在第一次分配之后分配大量内存。其次,在创建新线程时,这将使用相同的地址空间,因此不会创建额外的映射。

我将假设您希望在用户空间中这样做,因为在内核空间中,您可以做很多事情来使这个探索变得有点退化(例如,您可以尝试将页面映射到相同的位置)。相反,您希望使用mmap分配匿名页。Mmap是一个显式调用,用于创建一个虚拟内存条目,以便当第一次访问特定页面时,内核实际上可以在该位置放置一些空白物理内存。导致故障的是对该位置的第一次访问,第一次访问将实际使用PTE和PUD中的锁。

确保良好的基准程序:

  1. 如果您只是试图强调页面表,您可能也希望在该过程中关闭透明的巨大页面。(要查看的syscall是带有标志DISABLE_THP的prnctl )。在生成任何子进程之前运行此操作。
  2. Pin thread使用cpuet.
  3. 显式控制您感兴趣的区域,因此您希望为所有共享相同页表的每个线程选择特定地址。通过这种方式,您可以确保使用最大锁数。thread.
  4. Compare
  5. 使用psuedo随机函数将不同的种子写入到每个

的位置,该位置具有完全相同的基线,但地址空间中有非常不同的部分,即stressed.

  1. Make,它确保基线和过度满足的工作负载之间差别很小。
  2. 不会过度订阅处理器,这将导致由于上下文切换而造成的开销,这些切换臭名昭著地要根除。
  3. 确保在创建线程后开始捕获计时,并在线程被销毁之前停止它。

这在每一个线程中转换为什么:

代码语言:javascript
运行
复制
address = <per-thread address>
total = 0;
for(int i = 0; i < N; i++) 
{
 uint64_t* x = (uint64_t*) mmap((void*) address, 4096, PROT_READ | PROT_WRITE, 
     MAP_ANONYMOUS, -1, 0); //Maps one page anonymously
 assert(x);
 *x ^= pseudo_rand(); // Accesses the page and causes the allocation
 total += *x; // For fun
 int res = munmap((void*) x, 4096); //Deallocates the page (similar locks)
 assert(!res);
}

最重要的是:

allocation.

  • The

  • 使用mmap并显式地访问分配的位置来实际控制各个页面,地址的紧凑性决定了哪些锁是内核,而虚拟内存则需要在基准测试过程中遵守严格的规则。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71698978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档