# damocles-worker PC1 HugeTLB Pages 支持

在 PC1 阶段 rust-fil-proofs 会 mmap 两块和扇区大小一致的大块内存。这两块内存如果和 PC1 工作线程在同一 NUMA 节点会有效提升性能,使用 HugeTLB Pages (opens new window) 也会带来一定的性能提升。

经过测试,即便配置了 numa_preferred 在运行一段时间后,系统也经常会跨 NUMA 节点申请这两块内存。使用我们改造后的 rust-fil-proofs (opens new window) (当前版本的 damocles-worker 已支持) 可以使用预先创建好的和扇区大小一致的 hugepage 内存文件,该内存文件仅供上述 PC1 阶段的两大块内存的需求使用。可以一定程度上解决问题。

提示:原本的 mmap 方式优势在于由于 mmap 申请的内存由操作系统管理,即便在内存不足的情况下也能正常工作(内存严重不足可能会导致性能下降),用户可以根据自己的需要自行选择是否使用此功能。

# 使用方法

下文将演示启用两个 PC1 外部执行器子进程,两个 PC1 子进程分别运行在 NUMA0 和 NUMA1。并且每个 PC1 子进程的并发数为 1。

# 1. 为每个 NUMA node 分配足够的 Persistent hugepages.

单个 PC1 任务需要 64 GiB 的 persistent hugepages, 用户应该按照自己的需求分配足够的 persistent hugepages。

下面命令演示分配 128 GiB 的 persistent hugepages:

$ # 为 NUMA node 0 分配 64GiB, PageSize 为 1GiB 的 Persistent HugeTLB Pages 内存
$ echo "64" | sudo tee /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages
$ # 为 NUMA node 1 分配 64GiB, PageSize 为 1GiB Persistent HugeTLB Pages 内存
$ echo "64" | sudo tee /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages

更多信息请参考 HugeTLB Pages (opens new window)

# 2. 挂载 hugetlbfs

sudo mkdir /mnt/huge_1g
sudo mount -t hugetlbfs -o pagesize=1g none /mnt/huge_1g

上面的 mount 命令会挂载 (虚拟) 文件系统 hugetlbfs/mnt/huge_1g 目录。在 /mnt/huge_1g 目录中创建的任何文件都会使用 huge pages。

更多信息请参考 Using Huge Pages (opens new window)

# 3. 使用 damocles-worker-store-hugepage-init 工具创建 hugepage 内存文件

Usage:

damocles-worker-store-hugepage-file-init 

USAGE:
   damocles-worker store hugepage-file-init --node <numa_node_index> --num <number_of_files> --path <path> --path_pattern <path_pattern> --size <size>

FLAGS:
   -h, --help       
            Prints help information

   -V, --version    
            Prints version information


OPTIONS:
   -n, --node <numa_node_index>         
            Specify the numa node

   -c, --num <number_of_files>          
            Specify the number of hugepage memory files to be created

      --path <path>                    
            Specify the path to the output hugepage memory files and using the default pattern
            (/specified_hugepage_file_path/numa_$NUMA_NODE_INDEX).
            The created files looks like this:
            /specified_hugepage_file_path/numa_0/file
            /specified_hugepage_file_path/numa_1/file
            /specified_hugepage_file_path/numa_2/file
            ...
            
            This argument will be ignored if `path_pattern` is specified.
      --path_pattern <path_pattern>    
            Specify the path pattern for the output hugepage memory files where $NUMA_NODE_INDEX represents 
            the numa node index placeholder, which extracts the number in the folder name as the numa node index.
            
            If both the argument `path` and the argument `path_pattern` are specified, the argument `path` will be
            ignored.
   -s, --size <size>                    
            Specify the size of each hugepage memory file. (e.g., 1B, 2KB, 3kiB, 1MB, 2MiB, 3GB, 1GiB, ...)

Example:

$ # 在 NUMA 节点 0 上创建 2 个大小为 32GiB 的 hugepage 内存文件
$ sudo ./dist/bin/damocles-worker store hugepage-file-init --node=0 --num=2 --size=32GiB --path="/mnt/huge_1g/pc1_1"

$ # 在 NUMA 节点 1 上创建 2 个大小为 32GiB 的 hugepage 内存文件
$ sudo ./dist/bin/damocles-worker store hugepage-file-init --node=1 --num=2 --size=32GiB --path="/mnt/huge_1g/pc1_2"

$ tree /mnt/huge_1g
/mnt/huge_1g
├── pc1_1
│   └── numa_0
│       ├── 32.0_GiB_0
│       └── 32.0_GiB_1
└── pc1_2
    └── numa_1
        ├── 32.0_GiB_0
        └── 32.0_GiB_1

4 directories, 4 files

# 4. 配置 pc1 processor

# damocles-worker.toml

[[processors.pc1]]
# ...
envs = { HUGEPAGE_FILES_PATH = "/mnt/huge_1g/pc1_1", ... }
concurrent = 1
# ...

[[processors.pc1]]
# ...
envs = { HUGEPAGE_FILES_PATH = "/mnt/huge_1g/pc1_2", ... }
concurrent = 1
# ...

# 5. 启动 damocles-worker

启动 damocles-worker 后,如果日志级别为 trace 并且出现以下日志则表示 HugeTLb files 配置成功。

2022-08-19T10:12:14.731440277+08:00 TRACE ThreadId(01) storage_proofs_porep::stacked::vanilla::memory_handling::numa_mem_pool: loaded memory file: /mnt/huge_1g/processor_a/numa_0/32.0_GiB_0
2022-08-19T10:12:14.749523696+08:00 TRACE ThreadId(01) storage_proofs_porep::stacked::vanilla::memory_handling::numa_mem_pool: loaded memory file: /mnt/huge_1g/processor_a/numa_0/32.0_GiB_1
2022-08-19T10:12:14.767479765+08:00 TRACE ThreadId(01) storage_proofs_porep::stacked::vanilla::memory_handling::numa_mem_pool: loaded memory file: /mnt/huge_1g/processor_a/numa_1/32.0_GiB_0
2022-08-19T10:12:14.785486639+08:00 TRACE ThreadId(01) storage_proofs_porep::stacked::vanilla::memory_handling::numa_mem_pool: loaded memory file: /mnt/huge_1g/processor_a/numa_1/32.0_GiB_1
2022-08-19T10:12:14.78549745+08:00 TRACE ThreadId(01) storage_proofs_porep::stacked::vanilla::memory_handling::numa_mem_pool: number of loaded memory files: numa_id: 0, loaded: 2; numa_id: 1, loaded: 2