RDMA HCA/TCA
时间: 2023-12-02 17:43:09 浏览: 244
RDMA HCA/TCA是一种高速网络适配器,它使用RDMA技术来提高数据传输的效率和性能。HCA代表Host Channel Adapter,而TCA代表Target Channel Adapter。HCA通常安装在主机上,而TCA通常安装在存储设备上。这两种适配器都支持RDMA技术,可以通过RDMA协议进行高速数据传输。
RDMA技术是一种零拷贝技术,它可以直接在内存中传输数据,而不需要将数据从内存复制到网络适配器的缓冲区中。这种技术可以显著提高数据传输的效率和性能,减少CPU的负载,降低网络延迟和网络拥塞。
RDMA HCA/TCA通常使用InfiniBand或者RoCE(RDMA over Converged Ethernet)网络来进行高速数据传输。这些网络可以提供非常低的延迟和高的带宽,适用于高性能计算、云计算、大数据分析等领域。
以下是一个使用RDMA Write with Immediate Data的例子:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <infiniband/verbs.h>
#define MSG_SIZE 1024
#define RDMA_BUF_SIZE 1024
struct rdma_context {
struct ibv_context *ctx;
struct ibv_pd *pd;
struct ibv_mr *mr;
struct ibv_cq *cq;
struct ibv_qp *qp;
struct ibv_comp_channel *comp_channel;
struct ibv_port_attr port_attr;
char *rdma_buf;
uint32_t rkey;
uint64_t remote_addr;
};
int main(int argc, char *argv[])
{
struct rdma_context ctx;
struct ibv_device **dev_list;
struct ibv_device *ib_dev;
struct ibv_qp_init_attr qp_init_attr;
struct ibv_qp_attr qp_attr;
struct ibv_wc wc;
int num_devices;
int ret;
int i;
/* 获取IB设备列表 */
dev_list = ibv_get_device_list(&num_devices);
if (!dev_list) {
perror("ibv_get_device_list");
return -1;
}
/* 选择第一个IB设备 */
ib_dev = dev_list[0];
if (!ib_dev) {
fprintf(stderr, "No IB devices found\n");
return -1;
}
/* 打开IB设备 */
ctx.ctx = ibv_open_device(ib_dev);
if (!ctx.ctx) {
perror("ibv_open_device");
return -1;
}
/* 创建PD */
ctx.pd = ibv_alloc_pd(ctx.ctx);
if (!ctx.pd) {
perror("ibv_alloc_pd");
return -1;
}
/* 分配内存 */
ctx.rdma_buf = malloc(RDMA_BUF_SIZE);
if (!ctx.rdma_buf) {
perror("malloc");
return -1;
}
/* 注册内存 */
ctx.mr = ibv_reg_mr(ctx.pd, ctx.rdma_buf, RDMA_BUF_SIZE, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE);
if (!ctx.mr) {
perror("ibv_reg_mr");
return -1;
}
/* 创建CQ */
ctx.cq = ibv_create_cq(ctx.ctx, 1, NULL, NULL, 0);
if (!ctx.cq) {
perror("ibv_create_cq");
return -1;
}
/* 创建QP */
memset(&qp_init_attr, 0, sizeof(qp_init_attr));
qp_init_attr.send_cq = ctx.cq;
qp_init_attr.recv_cq = ctx.cq;
qp_init_attr.qp_type = IBV_QPT_RC;
qp_init_attr.cap.max_send_wr = 1;
qp_init_attr.cap.max_recv_wr = 1;
qp_init_attr.cap.max_send_sge = 1;
qp_init_attr.cap.max_recv_sge = 1;
ctx.qp = ibv_create_qp(ctx.pd, &qp_init_attr);
if (!ctx.qp) {
perror("ibv_create_qp");
return -1;
}
/* 修改QP状态 */
memset(&qp_attr, 0, sizeof(qp_attr));
qp_attr.qp_state = IBV_QPS_INIT;
qp_attr.pkey_index = 0;
qp_attr.port_num = 1;
qp_attr.qp_access_flags = IBV_ACCESS_REMOTE_WRITE;
ret = ibv_modify_qp(ctx.qp, &qp_attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
if (ret) {
perror("ibv_modify_qp");
return -1;
}
/* 获取端口属性 */
ret = ibv_query_port(ctx.ctx, 1, &ctx.port_attr);
if (ret) {
perror("ibv_query_port");
return -1;
}
/* 创建Completion Channel */
ctx.comp_channel = ibv_create_comp_channel(ctx.ctx);
if (!ctx.comp_channel) {
perror("ibv_create_comp_channel");
return -1;
}
/* 将CQ绑定到Completion Channel */
ret = ibv_req_notify_cq(ctx.cq, 0);
if (ret) {
perror("ibv_req_notify_cq");
return -1;
}
/* 等待CQ事件 */
ret = ibv_get_cq_event(ctx.comp_channel, &ctx.cq, &ctx.ctx);
if (ret) {
perror("ibv_get_cq_event");
return -1;
}
/* 请求下一个CQ事件 */
ret = ibv_req_notify_cq(ctx.cq, 0);
if (ret) {
perror("ibv_req_notify_cq");
return -1;
}
/* 获取远程节点的rkey和地址 */
ctx.rkey = 0x12345678;
ctx.remote_addr = 0xdeadbeef;
/* 向远程节点发送数据 */
memset(ctx.rdma_buf, 0, RDMA_BUF_SIZE);
strcpy(ctx.rdma_buf, "Hello RDMA!");
struct ibv_send_wr wr, *bad_wr;
struct ibv_sge sge;
memset(&wr, 0, sizeof(wr));
wr.wr_id = 0;
wr.opcode = IBV_WR_RDMA_WRITE_WITH_IMM;
wr.send_flags = IBV_SEND_SIGNALED;
wr.imm_data = 0x1234;
wr.wr.rdma.remote_addr = ctx.remote_addr;
wr.wr.rdma.rkey = ctx.rkey;
wr.sg_list = &sge;
wr.num_sge = 1;
sge.addr = (uintptr_t)ctx.rdma_buf;
sge.length = strlen(ctx.rdma_buf) + 1;
sge.lkey = ctx.mr->lkey;
ret = ibv_post_send(ctx.qp, &wr, &bad_wr);
if (ret) {
perror("ibv_post_send");
return -1;
}
/* 等待发送完成 */
do {
ret = ibv_poll_cq(ctx.cq, 1, &wc);
if (ret < 0) {
perror("ibv_poll_cq");
return -1;
}
} while (ret == 0);
/* 检查发送状态 */
if (wc.status != IBV_WC_SUCCESS) {
fprintf(stderr, "Send failed with status %d\n", wc.status);
return -1;
}
/* 关闭QP */
ret = ibv_destroy_qp(ctx.qp);
if (ret) {
perror("ibv_destroy_qp");
return -1;
}
/* 关闭Completion Channel */
ret = ibv_destroy_comp_channel(ctx.comp_channel);
if (ret) {
perror("ibv_destroy_comp_channel");
return -1;
}
/* 关闭CQ */
ret = ibv_destroy_cq(ctx.cq);
if (ret) {
perror("ibv_destroy_cq");
return -1;
}
/* 注销内存 */
ret = ibv_dereg_mr(ctx.mr);
if (ret) {
perror("ibv_dereg_mr");
return -1;
}
/* 释放内存 */
free(ctx.rdma_buf);
/* 释放PD */
ret = ibv_dealloc_pd(ctx.pd);
if (ret) {
perror("ibv_dealloc_pd");
return -1;
}
/* 关闭IB设备 */
ret = ibv_close_device(ctx.ctx);
if (ret) {
perror("ibv_close_device");
return -1;
}
/* 释放IB设备列表 */
ibv_free_device_list(dev_list);
return 0;
}
```
阅读全文