InfiniBand: The Ultimate Networking Solution for High-Performance Computing
Infiniband - это высокоскоростная технология сетевого взаимодействия, которая обеспечивает низкий уровень задержки и высокую скорость передачи данных. Она позволяет объединять несколько серверов в кластер и работать с ними как с единым целым.
Основные преимущества Infiniband:
- высокая скорость передачи данных (до 100 Гбит/с)
- низкий уровень задержки (от 1 мкс и меньше)
- высокая пропускная способность (до 200 млн сообщений в секунду)
Пример кода на языке программирования C++ для работы с Infiniband:
cpp
#include
// создание контекста Infiniband
struct ibv_context *ctx = ibv_open_device(dev);
// создание completion канала
struct ibv_comp_channel *channel = ibv_create_comp_channel(ctx);
// создание дескрипторов областей памяти
struct ibv_mr *send_mr = ibv_reg_mr(pd, send_buf, send_buf_size, IBV_ACCESS_LOCAL_WRITE);
struct ibv_mr *recv_mr = ibv_reg_mr(pd, recv_buf, recv_buf_size, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE);
// создание очередей обмена сообщениями
struct ibv_cq *send_cq = ibv_create_cq(ctx, CQ_SIZE, NULL, channel, 0);
struct ibv_cq *recv_cq = ibv_create_cq(ctx, CQ_SIZE, NULL, channel, 0);
// создание QP
struct ibv_qp_init_attr qp_init_attr = {
.send_cq = send_cq,
.recv_cq = recv_cq,
.qp_type = IBV_QPT_RC,
.sq_sig_all = 0,
.cap = {
.max_send_wr = MAX_SEND_WR,
.max_recv_wr = MAX_RECV_WR,
.max_send_sge = MAX_SEND_SGE,
.max_recv_sge = MAX_RECV_SGE
}
};
struct ibv_qp *qp = ibv_create_qp(pd, &qp_init_attr);
// привязка QP к адресу Infiniband
struct ibv_qp_attr qp_attr = {
.qp_state = IBV_QPS_INIT,
.pkey_index = 0,
.port_num = port_num,
.qp_access_flags = IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_LOCAL_WRITE
};
ibv_modify_qp(qp, &qp_attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
// создание сообщения для отправки
struct ibv_send_wr send_wr = {
.wr_id = 0,
.next = NULL,
.sg_list = send_sgl,
.num_sge = send_sge,
.opcode = IBV_WR_RDMA_WRITE, // операция записи в область памяти получателя
.send_flags = IBV_SEND_SIGNALED,
.wr.rdma = {
.remote_addr = (uintptr_t) recv_buf, // адрес памяти получателя
.rkey = rkey
}
};
// отправка сообщения
struct ibv_send_wr *bad_send_wr;
ibv_post_send(qp, &send_wr, &bad_send_wr);
// обработка завершения операций
struct ibv_cq *cq;
void *cq_context;
struct ibv_wc wc;
while (ibv_get_cq_event(channel, &cq, &cq_context) == 0) {
ibv_ack_cq_events(cq, 1);
ibv_req_notify_cq(cq, 0);
while (ibv_poll_cq(cq, 1, &wc) == 1) {
// обработка завершения операции
}
}