---
title: Flat模式下片上内存编程
description: "Flat模式下DDR和片上内存作为独立的NUMA Node对用户可见，执行“numactl -H”命令，查看输出结果，其中0-15行是DDR（普通内存），16-31行是片上内存。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/KunpengDeveloper/usermanual/topic_0000002535456070.html
sourcePath: /source/zh/kunpenghpcs/KunpengDeveloper/usermanual/topic_0000002535456070.html
indexId: 1ebd6a9805e612b81f837e4da3da7d3e1c44f8cad847946452b05a85fc0bfa1d78
---
# Flat模式下片上内存编程

Flat模式下DDR和片上内存作为独立的NUMA Node对用户可见，执行“numactl -H”命令，查看输出结果，其中0-15行是DDR（普通内存），16-31行是片上内存。

图1 节点的DDR和片上内存分布

#### 方法一：使用malloc接口申请内存

该方法是程序使用malloc接口申请内存，运行程序时使用numactl命令绑定至NUMA Node的片上内存。该方法可以在程序无修改情况下，透明使用片上内存，是应用内存容量需求小于片上内存容量时的首选策略。

- 强制从指定的0 NUMA Node的片上内存分配内存，如果程序超出指定NUMA Node的容量，程序报错Out of Memory并中止。

  - numactl -mmemory_on_chip_node1 ./a.out
- 程序首先从指定的NUMA Node的片上内存开始分配内存，片上内存分配完后，会使用该Node的DDR内存继续分配。

  - numactl --preferredmemory_on_chip_node1 ./a.out

memory_on_chip_node1 表示指定的节点ID

a.out 表示要运行的程序的可执行文件


以下以启动560个进程，一个进程运行在一个核上举例：

mpirun -np 560 --rankfile rfile run_on_package_memory_node.sh

```
#!/bin/sh
memid=`expr ${OMPI_COMM_WORLD_LOCAL_RANK} /
35
`   # 每35个进程跑在一个numa上，就可以确定当前进程在第几个numa上
memid=`expr $memid + 16`                          # 放在
图1 节点的DDR和片上内存分布
的17行，也就是指定为片上内存模式
numactl -m ${memid} ./a.out                       # a.out表示运行的二进制
```


#### 方法二：使用KUPL接口申请片上内存

通过替换malloc函数来实现申请片上内存，举例如下

```
#include <kupl.h>
float *x = (float *)kupl_hbw_malloc(N*sizeof(float));
kupl_hbw_free(x);
```


#### 方法三：使用memkind接口申请片上内存

通过替换malloc函数来实现申请片上内存，举例如下

```
#include <hbwmalloc.h>
float *x = (float *)hbw_malloc(N*sizeof(float));
hbw_free(x);
```
