C语言 如何计算rte_mempool中可以分配的最大元素数?

2sbarzqh  于 2023-05-16  发布在  其他
关注(0)|答案(1)|浏览(175)

假设我们有16x1GB的大页面可用于DPDK。我们希望为一个mbufs内存池使用尽可能多的内存。在给定最大数据包大小的情况下,如何计算成功创建rte_mempool所需的最大数据包数量?
为简单起见,假设私有数据大小和高速缓存大小都为零:

const uint16_t max_rx_pkt_size = 9216;
// We have 16GB of hugepage memory
const uint32_t hugepage_size_bytes = 16U * 1024 * 1024 * 1024;
// How to calculate the max number of packets that we can allocate?
const uint32_t num_packets = hugepage_size_bytes / max_rx_pkt_size;
rte_mempool *mp = rte_pktmbuf_pool_create("rx_packet_pool", num_packets,
                                            0 /* Cache size */, 0 /* Private size */,
                                            max_rx_pkt_size, rte_socket_id());

上面对rte_pktmbuf_pool_create()的调用由于内存不足而失败,rte_errno被设置为ENOMEM。
显然,DPDK在内部为它的数据结构分配了一些内存,所以我们不能分配一个占用100%大页面内存的rte_mempool。
我们目前使用的解决方法是在计算num_packets之前减少hugepage_size_byteshugepage_size_bytes -= (hugepage_size_bytes / 32);然后我们最终得到一个较小的值num_packetsrte_pktmbuf_pool_create()成功。
但是,当我们将max_rx_pkt_size更改为不同的值时,比如1460,则内存池分配失败。这不是一个好办法。有没有一种方法可以通过编程检查(或者至少确定地估计)可以根据hugepage内存大小分配的mbufs的最大数量?

fhg3lkii

fhg3lkii1#

至少这个问题与OP的方法:

unsigned溢出

上面对rte_pktmbuf_pool_create()的调用由于内存不足而失败,rte_errno被设置为ENOMEM
是否会因为大小为零而失败?
对于32位unsigned,乘积为零。

16U * 1024 * 1024 * 1024 // overflow
// same as
0u

使用wider types when forming the constant并保存产品:

// const uint32_t hugepage_size_bytes = 16U * 1024 * 1024 * 1024;
const unsigned long long hugepage_size_bytes = 16LLU * 1024 * 1024 * 1024;

// Maybe add a check
if (hugepage_size_bytes / (UINT32_MAX + 1ull) >= max_rx_pkt_size) {
  Handle_size_too_big();
}

const uint32_t num_packets = hugepage_size_bytes / max_rx_pkt_size;

真实的分配?

我对rte_pktmbuf_pool_create()不熟悉,但在各种分配测试中,有时直到 used 才分配内存。
Why is malloc not "using up" the memory on my computer?的问题可能适用。

次要:类型

rte_pktmbuf_pool_create()的一个示例使用unsigned n而不是uint32_t n

struct rte_mempool *
rte_pktmbuf_pool_create(const char *name, unsigned n,
    unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
    int socket_id)

所以我建议匹配类型。

// const uint32_t num_packets = hugepage_size_bytes / max_rx_pkt_size;
const usigned num_packets = hugepage_size_bytes / max_rx_pkt_size;

详情

为了更好地评估“我们正在使用的当前解决方案”,请发布更完整的示例代码。

相关问题