출처: https://zcopy.wordpress.com/

설명: 원문을 직역한 것이 아니라 핵심 부분을 추출하여 RDMA 전송 작업을 소개합니다(나중에 RDMA 전송에 대한 언급은 IBA의 전송 작업에 해당함). 제공된 예제는 매우 간단하고 이해하기 쉬우므로 읽을 가치가 있습니다.

(공사 중)Remote Direct Memory Access(RDMA) Send 소개

1. RDMA란 무엇인가?

img

RDMA는 Remote Direct Memory 네트워크를 통해 두 응용 프로그램 간에 버퍼를 이동 하는 방법인 액세스입니다. RDMA 는 운영 체제를 우회하기 때문에 기존 네트워크 인터페이스와 다릅니다. 이를 통해 RDMA를 구현하는 프로그램은 다음을 가질 수 있습니다.

  1. 절대적으로 가장 낮은 대기 시간
  2. 최고의 처리량
  3. 가장 작은 CPU 풋프린트

RDMA는 원격 직접 메모리 액세스(Remote Direct Memory Access)의 약자로, 네트워크를 통해 두 애플리케이션 간에 버퍼의 데이터를 이동하는 방법입니다. RDMA는 운영 체제를 우회한다는 점에서 기존 네트워크 인터페이스와 다릅니다. 이를 통해 RDMA를 구현하는 프로그램은 다음을 수행할 수 있습니다.

  1. 절대 최소 대기 시간
  2. 최고 처리량
  3. 최소 CPU 풋프린트(즉, CPU 개입이 최소화된 경우)

2. RDMA 사용 방법

RDMA를 사용하려면 RDMA 엔진을 구현하는 네트워크 인터페이스 카드가 필요합니다.

이것을 HCA(호스트 채널 어댑터)라고 합니다. 어댑터는 PCI Express 버스를 통해 RDMA 엔진에서 응용 프로그램 메모리로의 채널을 생성합니다. 우수한 HCA는 유선을 통해 RDMA 프로토콜을 실행하는 데 필요한 모든 논리를 하드웨어에서 구현합니다. 이것은 흐름 제어 및 안정성뿐만 아니라 분할 및 재조립을 포함하므로 애플리케이션 관점에서 전체 버퍼를 처리하며 이 카드를 HCA(호스트 채널 어댑터)라고 합니다. 어댑터는 PCIe 버스를 통해 RDMA 엔진에서 애플리케이션 메모리로의 채널을 생성합니다. 우수한 HCA는 유선을 통해 RDMA 프로토콜을 구현하는 데 필요한 모든 로직을 하드웨어로 구현합니다. 여기에는 그룹화, 재조립, 흐름 제어 및 안정성 보장이 포함됩니다. 따라서 애플리케이션 관점에서는 모든 버퍼를 처리하는 역할만 담당합니다.

img

RDMA에서 우리는 커널 드라이버를 사용하여 데이터 채널을 설정합니다. 우리는 이것을 명령 채널이라고 부릅니다. 우리는 명령 채널을 사용하여 커널을 완전히 우회하여 데이터를 이동할 수 있는 데이터 채널을 설정합니다. 일단 이러한 데이터 채널을 설정하면 읽고 읽을 수 있습니다. 버퍼를 직접 쓰기 RDMA에서는 커널 모드 드라이버를 사용하여 데이터 채널을 설정합니다. 이것을 명령 채널이라고 합니다. 명령 채널을 사용하면 데이터를 이동할 때 커널을 완전히 우회할 수 있는 데이터 채널을 만들 수 있습니다. 이 데이터 채널이 설정되면 데이터 버퍼를 직접 읽고 쓸 수 있습니다.

이러한 데이터 채널을 설정하기 위한 API는 “verbs”라는 API에 의해 제공됩니다. verbs API는 OFED(Open Fabrics Enterprise Distribution)라는 오픈 소스 Linux 프로젝트에서 유지 관리됩니다. (www.openfabrics.org) 있습니다. 동일한 사이트에 있는 Windows WinOF에 해당하는 프로젝트 데이터 채널을 설정하는 API는 “동사”라는 API입니다. “동사” API는 OFED라는 Linux 오픈 소스 프로젝트에서 유지 관리합니다. 사이트 www.openfabrics.

verbs API는 익숙한 소켓 프로그래밍 API와 다릅니다. 그러나 몇 가지 개념을 배우면 실제로 사용하기가 훨씬 쉽고 프로그램 설계가 훨씬 간단합니다. “verbs” API는 소켓 프로그래밍 API와 다릅니다. 당신은 다릅니다. 그러나 몇 가지 개념에 익숙해지면 프로그램을 설계할 때 매우 쉽고 훨씬 더 쉽습니다.

3. 대기열 쌍

RDMA 작업은 메모리를 “고정”하는 것으로 시작됩니다. 메모리를 고정하면 커널에 이 메모리가 응용 프로그램에서 소유하고 있음을 알리는 것입니다. 이제 HCA에 메모리 주소를 지정하고 카드에서 메모리로의 채널을 준비하도록 지시합니다. 우리는 다음을 참조합니다. 이것은 메모리 영역 을 등록하는 것과 같습니다 . 이제 수행하려는 RDMA 작업에 등록된 메모리를 사용할 수 있습니다. 아래 다이어그램은 등록된 영역과 통신 대기열에서 사용 중인 해당 영역 내의 버퍼를 보여줍니다.

RDMA 작업 기억을 “연결”하기 시작합니다. 메모리에 “참여”할 때 커널에 이 메모리에 소유자가 있고 소유자가 애플리케이션임을 알리는 것입니다. 따라서 HCA에 이 메모리 섹션을 처리하도록 지시하고 HCA 카드에서 이 메모리 섹션으로의 채널을 열 준비를 신속하게 수행합니다. 이 작업을 메모리 영역(MR) 등록이라고 합니다. MR이 등록되면 모든 RDMA 작업에 이 메모리를 사용할 수 있습니다. 아래 그림에서 등록된 메모리 영역( MR )과 통신 큐가 사용하는 메모리 영역 내부에 위치한 버퍼(buffer)를 볼 수 있습니다.

img

RDMA 통신은 3개의 큐 세트를 기반으로 합니다. 송신 큐와 수신 큐는 작업 스케줄링을 담당합니다. 항상 쌍으로 생성됩니다. 큐 쌍(QP) 이라고 합니다. 완료 큐(CQ)가 사용됩니다. 작업 대기열에 배치된 지침이 완료되면 알려주기 위해 RDMA 통신은 세 개의 대기열(SQ, RQ 및 CQ) 모음을 기반으로 합니다. 그 중 SQ(Sending Queue)RQ(Receive Queue) 는 작업 스케줄링을 담당하며 항상 쌍으로 생성되며 이를 QP(Queue Pair) 라고 합니다. 완료 큐(CQ)는 작업 큐에 배치된 명령이 완료될 때 알림을 보내는 데 사용됩니다 .

사용자는 HCA에 전송하거나 수신하려는 버퍼를 알려주는 명령을 작업 대기열에 배치합니다. 이러한 명령은 작업 요청 또는 작업 대기열 요소(WQE) 라고 하는 작은 구조체입니다.. WQE는 starwars의 생물체처럼 “WOOKIE”로 발음됩니다. WQE는 주로 버퍼에 대한 포인터를 포함합니다. 전송 대기열에 배치된 WQE는 전송할 메시지에 대한 포인터를 포함합니다. 수신 대기열의 WQE에 있는 포인터는 다음을 포함합니다. 회선에서 들어오는 메시지를 배치할 수 있는 버퍼에 대한 포인터

사용자가 명령을 작업 대기열에 넣으면 데이터를 수신하기 위해 어떤 버퍼를 보내거나 사용해야 하는지 HCA에 알리는 것을 의미합니다. 이러한 지침은 WR(작업 요청) 또는 WQE(작업 대기열 요소 )라고 하는 작은 구조 입니다. WQE는 스타워즈의 야수처럼 “WOOKIE”로 발음됩니다. WQE는 주로 버퍼에 대한 포인터를 포함합니다. 송신 대기열(SQ)에 배치된 WQE에는 보낼 메시지에 대한 포인터가 포함되어 있습니다. 수신 큐의 WQE에 있는 포인터는 수신할 메시지를 저장하는 데 사용되는 버퍼를 가리킵니다.

RDMA는 비동기 전송 메커니즘입니다. 따라서 한 번에 많은 수의 WQE를 보내거나 받을 수 있습니다. HCA는 이러한 WQE를 최대한 빨리 순서대로 처리합니다. WQE가 처리되면 데이터가 이동됩니다.CQE(Completion Queue Element) 가 생성되어 CQ(Completion Queue)에 배치됩니다. CQE를 “COOKIE”라고 합니다.

RDMA는 비동기 전송 메커니즘입니다. 따라서 한 번에 작업 대기열에 여러 WQE를 보내거나 받을 수 있습니다. HCA는 이러한 WQE를 가능한 한 빨리 순차적으로 처리합니다. WQE가 처리되면 데이터가 이동됩니다. 전송이 완료되면 HCA는 완료 대기열 요소(CQE) 를 생성하여 완료 대기열(CQ)에 배치합니다. 이에 따라 CQE는 “COOKIE”로 발음됩니다.


4. 간단한 예제

이 예제에서는 시스템 A의 메모리에서 시스템 B의 메모리로 버퍼를 이동합니다. 이것이 우리가 메시지 전달 의미론이라고 부르는 것입니다. 작업은 SEND입니다. RDMA의 가장 기본적인 형태로 간단한 예를 들어보겠습니다.

이 예에서는 시스템 A의 메모리에서 시스템 B의 메모리로 버퍼의 데이터를 이동합니다. 이것이 우리가 메시징 의미론이라고 부르는 것입니다. 다음으로 이야기할 작업은 RDMA에서 가장 기본적인 작업 유형인 SEND입니다.

1단계 시스템 A와 B는 QP의 완료 대기열을 생성하고 RDMA가 발생하도록 메모리에 영역을 등록했습니다. 시스템 A는 시스템 B로 이동하려는 버퍼를 식별합니다. 시스템 B에는 데이터를 위해 할당된 빈 버퍼가 있습니다. 1단계: 시스템A와 B 모두 각자의 QP에 대한 완료 대기열(CQ)을 만들고 다가오는 RDMA 전송을 위해 해당 메모리 영역(MR)을 등록합니다. 시스템 A는 버퍼를 식별하고 이 버퍼의 데이터는 시스템 B로 이동됩니다. 시스템 B는 시스템 A에서 보낸 데이터를 저장하기 위해 빈 버퍼를 할당합니다.

img

2 단계시스템 B는 WQE “WOOKIE”를 생성하고 수신 대기열에 배치합니다. 이 WQE에는 데이터가 배치될 메모리 버퍼에 대한 포인터가 포함됩니다. 시스템 A는 또한 전송될 메모리의 버퍼를 가리키는 WQE를 생성합니다.

2단계: 시스템 B는 WQE를 생성하고 수신 대기열(RQ)에 배치합니다. 이 WQE에는 포인터가 포함되어 있으며 포인터가 가리키는 메모리 버퍼는 수신된 데이터를 저장하는 데 사용됩니다. 시스템 A는 또한 WQE를 생성하여 전송 대기열(SQ)에 배치합니다. WQE의 포인터는 데이터가 전송될 메모리 버퍼를 구현합니다.

img

3단계 HCA는 항상 전송 대기열에서 WQE를 찾는 하드웨어에서 작동합니다. HCA는 시스템 A에서 WQE를 소비하고 메모리 영역에서 시스템 B로 데이터 스트리밍을 시작합니다. 데이터가 시스템 B에 도착하기 시작하면 HCA는 소비합니다. 수신 대기열의 WQE는 데이터를 배치해야 하는 위치를 학습합니다. 데이터는 커널을 우회하는 고속 채널을 통해 스트리밍됩니다. 3단계:시스템 A의 HCA는 항상 하드웨어에서 작동하여 전송 대기열에 WQE가 있는지 확인합니다. HCA는 시스템 A에서 WQE를 소비한 다음 메모리 영역의 데이터를 데이터 스트림으로 변환하여 시스템 B로 보냅니다. 데이터 흐름이 시스템 B에 도달하기 시작하면 시스템 B의 HCA는 시스템 B의 WQE를 소비한 다음 데이터를 배치해야 하는 버퍼에 넣습니다. Express Lane을 통해 전송되는 데이터 스트림은 운영 체제 커널을 완전히 우회합니다.

img

4단계 데이터 이동이 완료되면 HCA는 CQE “COOKIE”를 생성합니다. 이것은 완료 대기열에 배치되고 트랜잭션이 완료되었음을 나타냅니다. 소비된 모든 WQE에 대해 CQE가 생성됩니다. 따라서 시스템 A의 CQ에서 CQE가 생성됩니다.

4단계: 데이터 처리가 완료되면 HCA는 A를 생성합니다 . CQE. 이 CQE는 완료 대기열(CQ)에 배치되어 데이터 전송이 완료되었음을 나타냅니다. HCA에서 WQE를 사용할 때마다 CQE가 생성됩니다. 따라서 CQE는 시스템 A의 완료 대기열에 배치되고, 해당 WQE의 전송 작업이 완료되었음을 의미합니다. 마찬가지로 CQE도 시스템 B의 완료 대기열에 배치되어 해당 WQE의 수신 작업이 완료되었음을 나타냅니다. 오류가 발생하면 HCA는 여전히 CQE를 생성합니다. CQE에는 전송 상태를 기록하는 필드가 포함되어 있다.

img

방금 시연한 트랜잭션은 RDMA SEND 작업입니다. Infiniband 또는 RoCE에서 상대적으로 작은 버퍼의 총 시간은 약 1.3µs입니다. 한 번에 많은 WQE를 생성함으로써 매초 수백만 개의 버퍼를 이동할 수 있습니다.

우리는 RDMA 전송을 예로 들었 습니다. 작업. IB 또는 RoCE에서 작은 버퍼에서 데이터를 전송하는 데 걸리는 총 시간은 약 1.3µs입니다. 동시에 많은 WQE를 생성함으로써 수백만 개의 버퍼에 저장된 데이터를 1초 이내에 전송할 수 있습니다.

5. 요약

이 레슨에서는 RDMA verbs API 사용을 시작할 수 있도록 소프트웨어를 얻는 방법과 위치를 보여주었습니다. 또한 RDMA 프로그래밍 패러다임의 기초가 되는 대기열 개념을 소개했습니다. 마지막으로 버퍼가 두 시스템 간에 이동하는 방법을 보여주어 RDMA SEND 작업 이 학습에서는 RDMA 동사 API를 사용하는 방법을 배웠습니다. 또한 RDMA 프로그래밍의 기초가 되는 대기열의 개념을 소개합니다. 마지막으로 RDMA 전송 작업을 시연하여 버퍼의 데이터가 한 시스템에서 다른 시스템으로 이동하는 방법을 보여줍니다.