Linux内核中页面表的PMD和PTE级别上有两个锁。每次线程/进程分配/映射一个内存时,它都应该持有其中一个锁,以便相应地更新页面表。很明显,随着线程数量的增加,保持锁的竞争也会增加。这可能会降低内存映射吞吐量,因为许多线程持有自旋锁。
我想为任务度量的是这些锁在内存映射吞吐量上的最坏的开销,但我不知道如何度量它。
我尝试在infinite-loop中使用infinite-loop,因为我增加了运行相同循环的线程数。我检查每一组正在运行的线程的/proc/{pid}/maps,以计数映射的内存数。但我不确定这是不是正确的方法。此外,这种方法消耗了大量的内存。
有什么有效的方法来测量这些锁的最坏的开销吗?
发布于 2022-03-31 23:00:17
很多评论都是正确的,但是我想我可能会试着完全的回答。首先,使用malloc不能显式控制页面映射,因为注释说stdlib的malloc部分实际上将在第一次分配之后分配大量内存。其次,在创建新线程时,这将使用相同的地址空间,因此不会创建额外的映射。
我将假设您希望在用户空间中这样做,因为在内核空间中,您可以做很多事情来使这个探索变得有点退化(例如,您可以尝试将页面映射到相同的位置)。相反,您希望使用mmap分配匿名页。Mmap是一个显式调用,用于创建一个虚拟内存条目,以便当第一次访问特定页面时,内核实际上可以在该位置放置一些空白物理内存。导致故障的是对该位置的第一次访问,第一次访问将实际使用PTE和PUD中的锁。
确保良好的基准程序:
的位置,该位置具有完全相同的基线,但地址空间中有非常不同的部分,即stressed.
。
这在每一个线程中转换为什么:
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.
mmap并显式地访问分配的位置来实际控制各个页面,地址的紧凑性决定了哪些锁是内核,而虚拟内存则需要在基准测试过程中遵守严格的规则。https://stackoverflow.com/questions/71698978
复制相似问题