<内核情景分析> 2.8:页面的定期换出 总结

主要的代码集中在2个内核线程kswapd和kreclaimd中,书中的分析主要集中在kswapd上。

Kswapd是一个无限循环,每过HZ个时间单位就被唤醒循环一次。每次循环中,使用inactive_shortage和free_shortage两个函数来判断是否存在可用物理页面短缺的情况。任何一个函数返回非零即认为物理页面短缺。

     出现物理页面短缺时,调用函数do_try_to_free_pages来腾出物理页面。函数首先调用free_shortage判断free状态的物理页面是否短缺,然后判断inactive_dirty状态的页面数量是否已经大于free和inactive_clean状态页面数量的总和。上述两个判断任何一个为非零则调用page_launder来扫描并处理inactive_dirty页面队列。Page_launder函数只负责处理inactive_dirty队列中的物理页面,其余的物理页面不属于此函数的处理范围。Page_launder首先对inactive_dirty队列中的每个物理页面做一些检查和处理,将不应在此队列中的物理页面调回active等等队列。确实应该在inactive_dirty队列中的page,如果正在使用(被I/O锁住),则调整至队尾。没有正在使用的page调用page->mapping->a_ops->writepage写回交换设备。如果page->buffer不为空,还需要调用try_to_free_buffers来处理。Try_to_free_buffers函数属于文件系统,本节未作深入分析。上述工作做完后,再调用free_shortage判断一次,如果结果仍然是非零,则重新对inactive_dirty队列中的page处理一次,然后page_launder函数返回。

Page_launder返回后,do_try_to_free_pages再次使用free_shortage+inactive_shortage判断物理页面情况。如果任何一个函数返回非零,则调用shrink_dcache_memory和shrink_icache_memory来释放文件数据和inode相关cache内存。本节未对这2个函数做深入分析。2个函数调用完成后,调用refill_inactive函数来处理active队列中的page。

Refill_inactive函数会以不同优先级扫描6次active队列,每次扫描的page数量逐次增加。每次循环中,调用refill_inactive_scan扫描active队列中的page,根据page结构中的PG_reference标志位来调整page结构中的age项。调用refill_active_scan时如果此标志位为1,则page最近被访问过,age增加PAGE_AGE_ADV(定义为3),否则age减半。当age为0的时候,如果page的引用计数为0(buffer不为空是如果引用计数为1)则将此page从active队列移至inactive_dirty队列。如果age不为0,则将此page移动至active队列的尾部。

Refill_inactive_scan返回后,refill_inactive的循环中接着调用swap_out来处理单个进程的active物理页面。每次swap_out只会处理1个进程,选择方法为:看看哪个进程中未被扫描过的物理页最多(mm->swap_cnt最大)。如果所有进程的mm->swap_cnt都为0,则重新将所有进程的此项数据初始化为进程专用所有物理页面的数量(mm->rss),然后选物理页面最多的。选出进程后,从vma向下至pgd,pmd逐pte进行处理。对于每个pte,调用try_to_swap_out。Try_to_swap_out首先根据pte的值找到对用页面的page结构,然后根据pte中的PAGE_ACCESSED标志位调整page结构中的age数据,调整方法与refill_inactive_scan一致。调整完成后,对于age为0的物理页面,如果此页面在交换设备上已经有对应的页面了,就增加交换设备上对应页面的使用计数,然后将交换设备对应页面的entry数据写入pte,此物理页面移至inactive_dirty队列。如果此时page只有引用计数为1,就进行buddy系统的合并。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kernel<<<>>>用法是指在CUDA编程中,使用<<<>>>符号来定义并行执行的内核函数。内核函数是在GPU上执行的函数,每个线程都会执行一次该函数。<<<>>>符号中的参数表示线程块(block)和线程(thread)的数量。例如,kernel<<<block, thread>>>()表示在block个线程块中,每个线程块中有thread个线程。 在上述示例中,kernel2和kernel3是两个并行执行的内核函数,<<<grid, block>>>表示在grid个线程块中,每个线程块中有block个线程。这样就可以同时启动多个线程块执行相同的内核函数。 在CUDA编程中,还可以使用__syncthreads()函数来同步线程。这个函数会让所有的线程在同一点等待,直到所有线程都执行到这个点。这可以用来确保线程之间的同步和协作。 另外,在示例中的cudaMemcpy()函数用于在主机和设备之间进行内存的数据传输。该函数的参数包括目标内存地址、源内存地址、数据数量和传输方向。例如,cudaMemcpy(dst, src, count, cudaMemcpyKind)表示将count个数据从src内存地址复制到dst内存地址。 综上所述,kernel<<<>>>用法是在CUDA编程中定义并行执行的内核函数,通过设置线程块和线程的数量来控制并发执行的规模。同时可以使用__syncthreads()函数来同步线程,以及使用cudaMemcpy()函数来进行主机和设备之间的数据传输。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [「并行学习」CUDA](https://blog.csdn.net/weixin_41468462/article/details/103378541)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值