在 Linux on POWER 上利用透明大内存页(5)用大内存页备份 malloc 命令
- UID
- 1066743
|
在 Linux on POWER 上利用透明大内存页(5)用大内存页备份 malloc 命令
首先来看看 malloc 命令,因为它简单且无需特殊链接。假设您当前以用户身份运行(在本例中,为 wmb),该用户包含在之前定义好的 libhuge 组中。挂载后的 libhugetlbfs 文件系统将 libhuge 作为该组的所有者,wmb 属于该组,如 所示。
清单 11. libhuge 组1
2
3
4
5
| wmb@p5sys:~> ls -l -d /libhugetlbfs/
drwxrwx--- 2 root libhuge 0 2006-12-18 21:26 /libhugetlbfs/
wmb@p5sys:~> id
uid=1000(wmb) gid=100(users) groups=16(dialout),33(video),100(users),1000(libhuge)
|
然后使用一个简单的程序来从一个大型的数组复制值到另一个数组。所创建的程序名为 copy_arrays.c,如 所示。
清单 12. copy_arrays.c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| #define ELEMENTS 1024*1024*128
static double bss_array_from[ELEMENTS];
static double bss_array_to[ELEMENTS];
static double *malloc_array_from;
static double *malloc_array_to;
int main() {
int i;
malloc_array_from = (double *)malloc(ELEMENTS*sizeof(double));
malloc_array_to = (double *)malloc(ELEMENTS*sizeof(double));
/* initialize and touch all of the pages */
for (i = 1; i < ELEMENTS; i++) {
bss_array_to = 1.0;
bss_array_from = 2.0;
malloc_array_to = 3.0;
malloc_array_from = 4.0;
}
/* copy "from" "to" */
for (i = 1; i < ELEMENTS; i++) {
bss_array_to = bss_array_from;
malloc_array_to = malloc_array_from;
}
return;
}
|
以根用户身份,分配 200 个大内存页给系统使用。然后打开第二个窗口并发出 watch 命令来跟踪大内存页的系统使用情况,如下所示:
1
2
| # echo 200 > /proc/sys/vm/nr_hugepages
# watch cat /proc/meminfo
|
以非根用户的身份(在本例中,即 wmb),编译和运行该程序,如 所示。被 “观察” 的大内存页的数量不应改变。但 “次数” 可能会因运行的系统的不同而有所不同。
清单 13. 运行 copy_arrays.c1
2
3
4
5
6
7
| wmb@p5sys:~> cc -O3 -m64 copy_arrays.c -o copy_arrays
wmb@p5sys:~> time ./copy_arrays
real 0m6.844s
user 0m2.149s
sys 0m2.649s
|
要用大内存页备份 malloc 命令,需要设置 HUGETLB_MORECORE 环境变量,并将 LD_PRELOAD 设为 libhugetlbfs 库,如 所示。程序应该执行得稍微快一些,您用来观察内存使用情况的窗口应该显示被分配和使用的大内存页。
清单 14. 设置 HUGETLB_MORECORE,其中 LD_PRELOAD 设为 libhugetlbfs 1
2
3
4
5
| wmb@p5sys:~> time HUGETLB_MORECORE=yes LD_PRELOAD=libhugetlbfs.so ./copy_arrays
real 0m6.480s
user 0m2.483s
sys 0m1.645s
|
根据您的系统和内存配置的不同,结果可能会有些差异,但在本例中,性能应该有 5% 左右(或 (6.480-6.844)/6.844)的提高。虽然这看起来是非常微小的一点时间,但若运行的是历时数天的计算密集型的工作负载,则性能改善的效果就会叠加。
SLES 10 上默认的堆栈大小在 SLES 10 上,默认的堆栈大小减少为 8192。所以若应用程序无意间遭遇 seg 错误,则需要查看 ulimit 是否设置为 8192。如果将堆栈大小设置为无限,比如 ulimit -s unlimited,则可能 避免这个问题。
LD_PRELOAD 设置会使 malloc 命令或其派生命令自动地由之前分配好的大内存页进行备份。 Malloc 命令在运行时处理,所以您将需要预定义足够多的 16MB 页供程序使用。 |
|
|
|
|
|