前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VPPinfra---vec简介

VPPinfra---vec简介

作者头像
dpdk-vpp源码解读
发布2023-01-04 12:36:12
8170
发布2023-01-04 12:36:12
举报
文章被收录于专栏:DPDK VPP源码分析

本文主要介绍vec函数的基本使用及内存分布情况,以及在工作中遇到的一些坑来分享一下。

基本介绍

Vectoe支持动态调整数组的大小和支持用户自定义头部,在vppinfra 其他数据结构中(pool heap hash)都能看到有使用,是最基本的数据结构。vectorj基础函数库也一直在更新变化,目前已经支持多numa。有些api接口也进行一些性能上优化,加入SIMA技术。 Vec基本的内存分布

代码语言:javascript
复制
                 User header (optional, uword aligned)
                   Alignment padding (if needed)
                   Vector length in elements
 User's pointer -> Vector element 0
                   Vector element 1
                   ...
                   Vector element N-1
#define vec_add2(V,P,N)           vec_add2_ha(V,P,N,0,0)

vec的相关api返回的V指向向量第0个元素的指针。 为了避免内存分配器的抖动,通常不会直接把内存释放掉,而是将V的长度置位0,但是保留其已分配的内存,以供下次使用。下面介绍典型使用二种对齐模式:

1、缺省对齐模式及no header
代码语言:javascript
复制
 这种模式在vpp源码中使用比较多的。大致结构如下:
代码语言:javascript
复制
#define vec_add2_ha(V,P,N,H,A)              \
do {                    \
  word _v(n) = (N);                \
  word _v(l) = vec_len (V);              \
  V = _vec_resize ((V), _v(n), (_v(l) + _v(n)) * sizeof ((V)[0]), (H), (A));  \
  P = (V) + _v(l);                \
} while (0)
/** \brief Add N elements to end of vector V,
    return pointer to new elements in P. (no header, unspecified alignment)

    @param V pointer to a vector
    @param P pointer to new vector element(s)
    @param N number of elements to add
    @return V and P (value-result macro parameters)
*/
#define vec_add2(V,P,N)           vec_add2_ha(V,P,N,0,0)
2、制定对齐长度及header长度

目前在最新的vpp代码中未找到使用的地方,在老版本16.9中临时存储发包的mbuf指针有使用,tx_vectors当成一个环形队列来使用,tx_ring_hdr_t存储环形队列使用情况;具体代码如下:

易犯的错

vec结构是最基础的类型,也是初学者很容易犯的错误:

代码语言:javascript
复制
Allocation only increases,Vector origin pointer may changer,store indexes(not pointers)!

1、vector 原始指针可能会改变,存储索引而不是指针。 主要时因为vec_add函数底层支持动态扩容(内存不足时,会进行3/2倍的扩容),扩容会改变原始v指针的指向,这点在使用中必须注意。 2、第一种说法也不是完全成立的。这种说法成立的前提是vector操作中不调用vec_del函数,否则也不能存储索引。 通过下面vec_del1的实现就可以确认;当del 索引不是最后一个时,处理逻辑是将最后一个赋值到当前需要删除的下标,并更新vec长度。由此可见存储索引也不是绝对安全的。

代码语言:javascript
复制
/** \brief Delete the element at index I

    @param V pointer to a vector
    @param I index to delete
*/
#define vec_del1(v,i)        \
do {            \
  uword _vec_del_l = _vec_len (v) - 1;    \
  uword _vec_del_i = (i);      \
  if (_vec_del_i < _vec_del_l)      \
    (v)[_vec_del_i] = (v)[_vec_del_l];    \
  _vec_len (v) = _vec_del_l;      \
  CLIB_MEM_POISON(vec_end(v), sizeof ((v)[0])); \
} while (0)

3、由于vec_del1删除处理逻辑,在遍历删除多个数据时,需要使用vec_foreach_backwards的方式来删除。避免出现漏删除的情况。

代码语言:javascript
复制
/** \brief Vector iterator */
#define vec_foreach(var,vec) for (var = (vec); var < vec_end (vec); var++)
/** \brief Vector iterator (reverse) */
#define vec_foreach_backwards(var,vec) \
for (var = vec_end (vec) - 1; var >= (vec); var--)

在vec_del1函数最后有个调用宏定义CLIB_MEM_POISON,特意跟踪了一下,最终调用的__asan_poison_memory_region,应该是一个内存越界的检测工具。

代码语言:javascript
复制
CLIB_MEM_POISON(vec_end(v), sizeof ((v)[0]))

#define ASAN_POISON_MEMORY_REGION(addr, size) \
  __asan_poison_memory_region((addr), (size)
#define CLIB_MEM_POISON(a, s)   ASAN_POISON_MEMORY_REGION((a), (s))
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DPDK VPP源码分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本介绍
    • 1、缺省对齐模式及no header
      • 2、制定对齐长度及header长度
      • 易犯的错
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档