Skip to content

Commit 90a02e2

Browse files
committed
docs(lab5): add boweraccess docs
Signed-off-by: Yiyang Wu <toolmanp@tlmp.cc>
1 parent 8b6f5da commit 90a02e2

File tree

5 files changed

+108
-6
lines changed

5 files changed

+108
-6
lines changed

Pages/Lab5/assets/example.jpg

146 KB
Loading

Pages/Lab5/base.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct fs_vnode {
4444

4545
FS_Base 的 IPC handler 在处理 IPC 请求时,会先把 IPC 消息中包含的文件 fd 转换为 fid,所以我们需要把进程的 fd 和实际所对应的文件表项的映射建立起来,而在 ChCore 中对应的就是 `server_mapping` 链表。每当处理 IPC 请求时,文件系统都会通过进程发起的 badge 号找到与之对应的映射表,最终得到文件表项的 ID。
4646

47-
> [!CODING] 练习5
47+
> [!CODING] 练习题 5
4848
> 实现 `user/system-services/system-servers/fs_base/fs_wrapper.c` 中的 `fs_wrapper_set_server_entry``fs_wrapper_get_server_entry` 函数。
4949
5050
> [!HINT] Tip
@@ -69,7 +69,7 @@ FS_Base 的 IPC handler 在处理 IPC 请求时,会先把 IPC 消息中包含
6969

7070
针对 mmap 操作,我们知道针对文件的 mmap 操作是采取 Demand Paging 的内存映射来实现的,当用户进程调用 `mmap` 时,FS 会首先为用户新增一个 `pmo` 即内存对象,并将其对应的类型设置为 `PMO_FILE`,并为其创建 `Page_Fault` 映射(`user/system-services/system-servers/fs_base/fs_page_fault.c`),最后将该 `pmo` 对象发回用户进程并让其进行映射。当用户尝试访问该内存对象,并发生缺页异常时,内核会根据 pmo 的所有者(badge)将异常地址调用到对应FS处理函数进行处理,处理函数为每一个文件系统中的 `user_fault_handler`,此时 FS 服务器会根据缺页地址分配新的内存页,填充文件内容并完成缺页的处理,最终返回内核态,从而递交控制权到原来的用户进程。
7171

72-
> [!CODING] 练习6
72+
> [!CODING] 练习题 6
7373
> 实现 `user/system-services/system-servers/fs_base/fs_wrapper_ops.c` 中的 `fs_wrapper_open``fs_wrapper_close``__fs_wrapper_read_core``__fs_wrapper_write_core`, `fs_wrapper_lseek`函数。
7474
7575
> [!HINT] Tip
@@ -81,9 +81,9 @@ FS_Base 的 IPC handler 在处理 IPC 请求时,会先把 IPC 消息中包含
8181
> - 你应当回顾 Lab2 的代码,去了解针对 PMO_FILE,内核是怎么处理缺页并将其转发到FS中的。同时你需要查看 `user/system-services/system-servers/fs_base/fs_page_fault.c` 中的 `page_fault` 处理函数,了解 FS 是如何处理 mmap 缺页异常的。
8282
8383
> [!SUCCESS]
84-
> 完成练习6后,执行 `make grade`,可以得到 `Scores: 100/100`
84+
> 完成练习题6后,执行 `make grade`,可以得到 `Scores: 100/100`
8585
86-
> [!QUESTION] 练习7
86+
> [!QUESTION] 思考题 7
8787
> 思考 ChCore 当前实现 VFS 的方式有何利弊?如果让你在微内核操作系统上实现 VFS 抽象,你会如何实现?
8888
8989
---

Pages/Lab5/bower.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# BowerAccess
2+
3+
4+
> [!NOTE]
5+
> large language models (LLMs) 在当今时代快速发展,成为新一代科技发展创新浪潮的热点。
6+
>
7+
> LLMs 通常具有数以亿计甚至数以百亿计的参数,这使得它们能够捕获语言中的复杂模式和语义关系,但也引入了极高的内存资源开销。以 GPT-3 举例,它的参数量为 175B,在未经优化的条件下,它的运行时内存开销大于 700GB 。这远远超出了许多边缘设备的 GPU 显存大小(如树莓派 4b 的 GPU 显存大小为 2GB)。
8+
>
9+
> PowerInfer 是发表在 SOSP'24 上的工作,它可以使得 175B 的 LLM 部署在单个商用级 GPU 上,这得益于它观察到了 LLM 访存的稀疏性。即在 LLM 中,并不是所有的神经元都对于计算结果有影响,只有少部分神经元会影响最终的结果,通过只将重要的神经元加载到 GPU 显存中,并选择性地对神经元进行计算,来减少 LLM 的运行时内存开销。
10+
11+
> [!WARNING]
12+
> 这是一个我们制作的新Lab, 欢迎大家测试并提出意见。
13+
14+
在 BowerAccess Lab 中,我们希望你参考 PowerInfer 的思想修改 chcore,进而在其上部署并优化一个与 LLM 类似的应用程序 `llm`(你可以在shell中通过`./llm`进行访问)。具体而言:
15+
16+
`llm` 是一个 CPU 内存开销极大的程序,它会使用 `mmap()` 映射一个 1MB 大小的**特殊内存空间**(用 `MAP_LLM` 进行标识)并访问其中的数据完成功能,这远远超过了 chcore 管理的 `MAP_LLM` 物理内存大小(出于题目设计考虑,我们将这种特殊内存空间的大小限制为 1MB),直接运行会产生大量的 Page Fault,引入了极大的运行时开销。
17+
18+
幸运的是,`llm` 的访存具有和 LLM 类似的稀疏性:
19+
20+
- 它虽然映射了非常大的内存空间,但是只会访问其中的一个特定的内存页面子集
21+
22+
- 只会按照单调递增的顺序访问内存页面
23+
24+
`llm``mmap()` 会传递一个特殊的特殊的 `MAP_LLM` 参数。
25+
26+
`llm` 的访存模式与下图相似(但访问的页面并不相同):
27+
28+
![example](assets/example.jpg)
29+
30+
虽然程序总共映射了 9 个页面,但是只访问了 `0, 2, 5, 6, 8` 这几个页面,且一定按照 `0 -> 2 -> 5 -> 6 -> 8` 的顺序访问,并没有访问 `1, 3, 4, 7` 这几个页面。
31+
32+
它的代码是(再次强调它只是示例代码,和真实的 `llm` 代码相似但不同):
33+
34+
```c
35+
#include <stdio.h>
36+
#include <stdlib.h>
37+
#include <fcntl.h>
38+
#include <sys/mman.h>
39+
#include <unistd.h>
40+
41+
#define PAGE_SIZE 4096
42+
43+
int main() {
44+
const char *filename = "weight.dat";
45+
int fd = open(filename, O_RDWR | O_CREAT, 0666);
46+
if (fd < 0) {
47+
perror("open");
48+
return EXIT_FAILURE;
49+
}
50+
51+
// alloc 9 pages
52+
if (ftruncate(fd, 9 * PAGE_SIZE) == -1) {
53+
perror("ftruncate");
54+
close(fd);
55+
return EXIT_FAILURE;
56+
}
57+
58+
// map the file, use the special `MAP_LLM` flag
59+
char *map = mmap(NULL, 9 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LLM, fd, 0);
60+
if (map == MAP_FAILED) {
61+
perror("mmap");
62+
close(fd);
63+
return EXIT_FAILURE;
64+
}
65+
66+
// access page 0, 2, 5, 6, 8
67+
int pages_to_access[] = {0, 2, 5, 6, 8};
68+
for (size_t i = 0; i < sizeof(pages_to_access) / sizeof(pages_to_access[0]); i++) {
69+
int page_number = pages_to_access[i];
70+
map[page_number * PAGE_SIZE] = 'A' + page_number;
71+
printf("Accessed page %d, first byte: %c\n", page_number, map[page_number * PAGE_SIZE]);
72+
}
73+
74+
if (munmap(map, 9 * PAGE_SIZE) == -1) {
75+
perror("munmap");
76+
}
77+
78+
close(fd);
79+
return EXIT_SUCCESS;
80+
}
81+
```
82+
83+
根据 `llm` 所具有的**稀疏的、可预测的**访存模式,我们可以设计在 page fault 发生时,预取(prefetch)即将访存的多个页面,这样就可以减少 page fault 的次数,提高了运行性能。
84+
85+
86+
> [!WARNING]
87+
> 我们只提供 `llm` 的二进制文件,并不提供源码文件。请自由发挥,判断出 `llm` 的具体访存模式。
88+
89+
> [!QUESTION] 思考题 8
90+
> 阅读 `kernel/object/user_fault.c` 下的 `sys_user_fault_map_batched` 函数,并回答如下问题
91+
> -`MAP_LLM` 地址空间具有容量限制”这个特点在代码中是如何实现的?
92+
> - 对比它和 `sys_user_fault_map` 函数的区别,并回答我们为什么需要引入一个新的系统调用?
93+
94+
> [!CODING] 练习题 9
95+
> 为了实现在 page fault 的时候预取页面的功能,我们需要修改 `user/system-services/system-servers/fs_base/fs_page_fault.c` 文件:
96+
> - 实现 `predict_prefetch_pages` 函数。
97+
> - 实现 `handle_one_fault` 函数中针对 `MAP_LLM` 的预取(prefetch)功能,实现需要 `predict_prefetch_pages``usys_user_fault_map_batched` 函数的配合。
98+
99+
---
100+
101+
> [!SUCCESS]
102+
> 以上为Lab5的所有内容

Pages/Lab5/posix.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ read(3, "", 131072) = 0
2727

2828
撇去一些无关紧要的系统调用后,我们可以看到其首先调用了`openat`这个系统指令,其负责打开一个系统路径下的文件,并返回其一个文件描述符号。
2929

30-
> [!CODING] 练习1
30+
> [!CODING] 练习题 1
3131
> 阅读 `user/chcore-libc/libchcore/porting/overrides/src/chcore-port/file.c``chcore_openat` 函数,分析 ChCore 是如何处理 `openat` 系统调用的,关注 IPC 的调用过程以及 IPC 请求的内容。
3232
3333
Lab5 的所有代码都运行在用户态,不同应用间通过 IPC 进行通信,可调用的 IPC 相关函数定义在 `user/chcore-libc/libchcore/porting/overrides/include/chcore/ipc.h`

Pages/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
- [Posix适配](./Lab5/posix.md)
4040
- [FSM](./Lab5/FSM.md)
4141
- [VFS(FS_Base)](./Lab5/base.md)
42-
42+
- [Boweraccess](./Lab5/bower.md)
4343
---
4444

4545
- [Detail: 源码详解](./Appendix/source-code.md)

0 commit comments

Comments
 (0)