DPDK-Hash(2)

简介: DPDK-Hash(2)

前言


第一章节介绍了DPDK的相关原理,和DPDK采用Cuckoo hash 相关性能指标。本章节主要是介绍DPDK hash 常用的 api 接口。


一、DPDK Hash


DPDK Hash Libary 提供函数主要是实现增加(add),删除(del), 查找(lookup),遍历(iterate)等功能。


二、DPDK hash 常用的API接口


1.DPDK 结构体

创建Hash 使用的参数结构体 如下:

/**
 * Parameters used when creating the hash table.
 */
struct rte_hash_parameters {
  const char *name;   /**< Name of the hash. */   //此名字具备唯一性, 在dpdk 中hash ,ring 等都需要唯一性名字
  uint32_t entries;   /**< Total hash table entries. */     // 创建的Hash 表容量,支持多少个条目
  uint32_t reserved;    /**< Unused field. Should be set to 0 */ // 保留
  uint32_t key_len;   /**< Length of hash key.*/ //每个Hash key 的长度。Hash 表中的Hash key 长度是统一的,有此处设置大小。
  rte_hash_function hash_func;  /**< Primary Hash function used to calculate hash. */ cuckoo Hask 需要两个Hash function,在这里设置Cuckoo Hash的主计算Function
  uint32_t hash_func_init_val;  /**< Init value used by hash_func. */
  int socket_id;      /**< NUMA Socket ID for memory. */ 此处表示Hash创建在那个物理socket_id 上。
  uint8_t extra_flag;   /**< Indicate if additional parameters are present. */
};

2. DPDK 常用接口

DPDK Hash API常用接口如下:

DPDK Hash API 大部分在<rte_hash.h> 中
// Hash table 的创建函数
struct rte_hash *rte_hash_create(const struct rte_hash_parameters *params);
// Hash add API 提供了四种
// hash_header + key
int32_t rte_hash_add_key(const struct rte_hash *h, const void *key);
// Hash_header + key + data. 在对应的Hash 表中存储数据data.
int rte_hash_add_key_data(const struct rte_hash *h, const void *key, void *data);
// Hash_headr +key + hask_function(slaver function)
int32_t rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t sig);
// Hash_hader+key+
int32_t rte_hash_add_key_with_hash_data(const struct rte_hash *h, const void *key,hash_sig_t sig, void *data);
// 删除
// 根据key 删除 
int32_t rte_hash_del_key(const struct rte_hash *h, const void *key);
// 根据key和slave Hash function vale 
int32_t rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t sig);
// 重置真个hash table
void rte_hash_reset(struct rte_hash *h);
// 遍历整个表
int32_t rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32_t *next);

三、DPDK 提供的Hash 算法


DPDK hash 提供了默认的默认的Hash 计算primary function. 如果不设置h->hash_func 就使用初始化默认的hash 函数


Hash 计算的slave function 可以使用rte_hash_hash(const struct rte_hash *h, const void *key) 获取。

Hash 计算函数可以自己定义: 比如l3fwd中。哈希函数就是自定义的。


四、DPDK Hash Demo


#include <stdio.h>
#include <arpa/inet.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
//#include <rte_log.h>
#include <rte_hash.h>
#include <rte_jhash.h>
// hash表,也就是实现增删改查等功能
#define HASH_ENTRI_MAXNUM 1<<12
#define HUSH_KEY_COUNT   1<< 4
// 创建Hash key。 此处采用TUPLE5
struct net_key {
  uint32_t sip;
  uint32_t dip;
  uint16_t sport;
  uint16_t dport;
  char proto;
};
static void print_key (struct net_key *key) {
  printf("sip: %x dip: %x sport: %x dport %x proto:%d \n", 
    key->sip, key->dip, key->sport, key->dport, key->proto);  
}
// DPDK 创建表,队列等都需要自定义名字
static struct rte_hash * create_hash_table(const char *name){
  struct rte_hash_parameters *param = (struct rte_hash_parameters *) malloc(sizeof(struct rte_hash_parameters));
  if (!param) return NULL;
  param->name = name;
  param->entries = HASH_ENTRI_MAXNUM;
  param->key_len = sizeof(struct net_key);
  param->hash_func = rte_jhash; //  hash 函数
  param->hash_func_init_val = 0;
  param->socket_id =rte_socket_id();               // 进行NUMA, 这个是表示每一块内存上的寻址。
  struct rte_hash *hash = rte_hash_create(param);
  if (hash == NULL) {
    //RTE_LOG(INFO, Hash, "========================\n");    
  }
  return hash;
}
//DPDK 添加方式有四种
int main(int argc, char *argv[]){
  // DPDK 环境初始化
  rte_eal_init(argc, argv);
  int i = 0;
  uint32_t  net_sip;
  uint32_t  net_dip;
  uint16_t  sport;
  uint16_t  dport;
  inet_pton(AF_INET,"192.168.1.1",&net_sip);
  inet_pton(AF_INET,"192.168.2.1", &net_dip);
  sport = htons(5000);
  dport = htons(6000);
  struct rte_hash *hash  = create_hash_table("cuckoo hash table");
  for (i = 0; i < HUSH_KEY_COUNT; i++){
    struct net_key *nk = malloc(sizeof(struct net_key));
    nk->sip = net_sip + i;
    nk->dip = net_dip + i;
    nk->sport = sport+ i;
    nk->dport = dport + i;
    nk->proto = i % 2;
    // key 
    // key hash
    // key data+
    // key hash, data
    if(i % 4 == 0) {
      //rte_hash_add_key(hash, nk);
    }else if(i % 4 == 1){ // 第二种添加
      hash_sig_t key2 = rte_hash_hash(hash, nk);
      rte_hash_add_key_with_hash(hash, nk, key2);
    }
    else if (i %4 == 2){ // 第三种添加
      uint32_t* tmpdata = (uint32_t *)malloc(sizeof(uint32_t));
      *tmpdata = i;
      rte_hash_add_key_data(hash, nk, (void *)tmpdata);
    }else {
      hash_sig_t key4 = rte_hash_hash(hash, nk);
      uint32_t* tmp = (uint32_t *)malloc(sizeof(uint32_t));
      *tmp= i;
      rte_hash_add_key_with_hash_data(hash, nk, key4, (void *)tmp);
    }
  }
#if 0
  for (i = 0;i < HUSH_KEY_COUNT;i ++) {
    struct net_key *nk = malloc(sizeof(struct net_key));
    nk->sip = net_sip + i;
    nk->dip = net_dip + i;
    nk->sport = sport+ i;
    nk->dport = dport + i;
    nk->proto = i % 2;
    int idx = rte_hash_lookup(hash, nk);
    printf("hash lookup --> sip: %x, idx: %d\n", nk->sip, idx);
    rte_hash_del_key(hash, nk);
    free(nk);
  } 
#endif
  struct net_key *key = NULL;
  void *value = NULL;
  uint32_t next =0;
  while (rte_hash_iterate( hash, (const void **)&key, &value,&next) >= 0){
    print_key(key);
    if (value != NULL)
      printf("value : %u \n", *(uint32_t*)value);
  }
  return 0;
}


结果 :


总结


提示:这里对文章进行总结:

目录
相关文章
|
7月前
|
存储 前端开发 Linux
DPDK-mempool(1)
DPDK-mempool(1)
153 0
|
7月前
|
存储 数据挖掘 API
DPDK_Hash(1)
DPDK_Hash(1)
197 0
|
7月前
|
存储 前端开发 JavaScript
hash 的特性与运用
hash 的特性与运用
|
7月前
|
存储 缓存 测试技术
DPDK-mempool(3)
DPDK-mempool(3)
162 0
|
NoSQL Redis
Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式
Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式
269 0
|
人工智能 程序员 开发者
《深入浅出DPDK》—第2章2.5节Cache预取
以上章节讲到了多种和Cache相关的技术,但是事实上,Cache对于绝大多数程序员来说都是透明不可见的。程序员在编写程序时不需要关心是否有Cache的存在,有几级Cache,每级Cache的大小是多少;不需要关心Cache采取何种策略将指令和数据从内存中加载到Cache中;也不需要关心Cache何时将处理完毕的数据写回到内存中。
4759 0
|
存储 算法 C#
C#实现Hash应用全解
C#实现Hash应用全解1、引言HASH是根据文件内容的数据通过逻辑运算得到的数值, 不同的文件(即使是相同的文件名)得到的HASH值是不同的。 Hash 通过一定的哈希算法(典型的有MD5,SHA-1等),将一段较长的数据映射为较短小的数据,这段小数据就是大数据的哈希值。
1448 0
|
存储 NoSQL Redis
redis必杀命令:哈希(Hash)
题记: Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
1042 0
|
Linux 数据处理
DPDK
数据平面开发套件(DPDK[1]  ,Data Plane Development Kit)是由6WIND,Intel等多家公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。
2263 0