20170925

NVMe 세미나
NVMe overview & NVMeDirect. 김형준 박사과정. 성균관대. 저장 장치가 PCIe를 사용하는 것으로 바뀌고 있다. 요즘 제일 핫한 것, 빠르게 발전되고 있는 것이 NVMe. 왜 PCIe를 쓰느냐? 빠르기도 하고 scalable하다. lane을 늘릴수록 성능이 scalable하게 늘어난다. Latency도 낮은 편이다. Power, cost 측면에서도 좋은 편이다. NVM Express는 non-volatile storage에 최적화됨. 최대 64K개의 queue를 가질 수 있어서 병렬성이 높다. Queue가 많아서 lock을 잡지 않고 입출력을 수행할 수 있다. 빠른 속도로 향상되고 있는 프로토콜이다. 성능 향상을 위한 optimization이 빠르게 받아들여지고 있다. SAS는 6micro sec이 걸린다면 NVMe는 2micro sec으로 매우 짧다. 한 개의 장치가 여러 개의 시스템에 연결될 수도 있음. 한 개의 컨트롤러에 여러 개의 네임스페이스가 있을 수도 있음. 큐에는 admin queue와 I/O queue가 있음. Admin queue는 4K의 queue가 있고, I/O queue에는 64K의 queue가 있다. 실제 장치에서는 더 적은 수의 queue를 지원하는 것이 일반적이다. 잘 지원하지 않는 경우도 있음. Completion queue마다 독립적인 MSI-X interrupt를 갖는다. Admin queue는 submission, completion queue가 1:1 매칭이어야 하지만, I/O queue는 그렇지 않다. Submission queue마다 doorbell이 있음. Polling 방식을 쓴다면 completion queue를 보고 있다가 반납하면 된다. 그렇지 않고 interrupt 방식을 쓴다면 interrupt를 받고 처리하면 된다. 처리한 다음에는 completion doorbell을 호출함으로써 해당 entry를 free해주어야 한다. Namespace, queue 초기화 방식에 대해 설명해주심. 컨트롤러 설정, capability 확인, 큐 생성 등의 순서로 진행됨. 인터럽트를 할지 아닐지를 큐를 초기화하는 단계에서 설정해야 함. 명령어별로 인터럽트를 쓸 것이냐 폴링을 쓸 것이냐를 결정할 수는 없음. 하이퍼쓰레드를 사용하는 경우에는 폴링이 더 느릴 수도 있다. 코어의 특성을 탄다고 함. CPU 연산 유닛을 공유하기 때문에 발생하는 문제임. PRP entry는 연결된 페이지의 물리적인 주소를 포함함. FUSE 연산을 사용하면 두 개의 연산을 묶어서 보낼 수 있다. 어떤 연산이 성공하면 다른 연산을 수행하는 것과 같은 연산을 하는 경우에 이같은 방식을 사용할 수 있음. 하지만 실제로 이러한 것을 지원하는 장치는 없음. Arbitration mechanism. submission queue가 여러 개 있을 때 여러 개의 queue에서 어떤 순서로 이를 빼내서 처리할 것인지를 정의하는 모델이다. controller register의 값을 봄으로써 arbitration mechanism의 지원 여부를 확인할 수 있다. Control register의 값을 변경함으로써 weighted round robin을 활성화할 수 도 있다. Round robin은 여러 개의 queue를 순서대로 처리하는 것. Arbitration burst를 설정해서 queue의 priority를 조정할 수 있음. Weighted round robin은 queue를 묶어서 weight를 주는 방식으로 round robin하는 것. Queue의 priority는 queue를 생성하는 순간에 지정하게 됨. 실행 중에는 priority를 변경할 수는 없음. NVMe와 specification과의 차이로 인한 security hole이 발생할 수 있지 않을까 하고 생각해 봄. Data set management를 사용하면 데이터 셋에 대한 특성을 줄 수 있는 것 같다. Directives를 사용하면 특성을 줄 수도 있고, 뭔가 장치에서 정보를 받아올 수도 있는 것 같다. Directives를 쓸 수 있는지는 identify 명령어에서 확인할 수 있음. Directives를 사용하는 것과 multistream을 사용하는 것은 별개이다. Stream은 비슷한 cycle을 갖는 데이터. 같이 invalidate될 데이터를 넣어두면 효율적이다. 이들을 stream이라고 부른다. 비슷한 lifecycle을 갖는 것을 블록에 나누어 저장한다(SSD에서). Garbage collection을 하는 순간에 maximum throughput을 낼 수 없기 때문에, 이를 알리기 위해 advanced background control이라는 것이 있음. Open channel.. 뭐시기 하시는 분들이 garbage collection에 불만이 있어서 이에 대해 벤더가 추가한 기능임. NVMe Direct는 user-level에서 스토리지에 바로 쓰겠다 하는 아이디어. 왜 user-level에서 해야 하는가? 커널에서 제공하는 추상 레이어는 성능에 좋지 않음. 어플리케이션 별로 specific한 정책을 적용하기에는 NVMe direct 방법이 좋음. 커널 발전 속도가 빨라서 커널 수준에 넣기도 쉽지 않음. User-speace에 admin tool이 있지만, queue의 생성과 삭제는 kernel에서 관리함. User space에서 관리하면 queue에 대한 race condition이 발생하지 않느냐 하는 질문을 광원이 형께서 하심. 하지만 여전히 queue를 접근하는 주체는 여러 개가 되지 않으므로 문제가 되지 않음. 기존에는 코어마다 submission queue가 있었는데, NVMe direct에서는 thread마다 submission queue를 갖도록 함. 사용자의 데이터를 NVMe에 보내려면 물리 주소를 보내줘야 하지 않느냐? 하는 인수의 질문이 있었음. 미리 주소를 변환해두는 optimization이 가능하기는 함. 어쨌든 주소 변환 과정이 필요하다. CPU와 NVMe 조합에 따라 성능이 달라짐. SPDK가 성능이 떨어지는 것처럼 보이는 경우가 있는데, 하이퍼쓰레딩 영향 때문임. 결론적으로는 SPDK와 NVMe direct의 성능은 같음. Polling으로 인한 CPU 성능 저하를 해소하기 위해 dynamic polling interval을 설정하는 기법을 제안함. Redis는 원래 쓰기 연산을 간헐적으로 수행하는데, 매 연산마다 쓰기 연산을 수행하도록 함. NVMe direct에는 block cache라는 write buffer가 있어서 SPDK보다 좋은 성능을 보였음. 지금은 SPDK에도 비슷한 것이 있다고 함. NVMe direct에 대해 어플리케이션 포팅이 안 된다는 문제가 있어서 이를 해결하기 위해 NVMe direct 2.0을 연구하기 시작함. 기존에는 POSIX 인터페이스를 갖고 있어서, 이들을 지원하기 쉽지 않음. ForestFS를 제안함. 이 위에 mongodb를 실행함. SPDK에도 blobFS라는 파일시스템이 있음. flat한 파일 시스템을 지원하며, in-place update는 지원하지 않음. NVMe-oF(NVME over Fabrics)라는 것이 있음. RDMA를 사용해 로컬 디바이스처럼 사용하도록 하는 것. 매우 많은 기업에서 이를 지원하고자 하고 있음. 로컬 스토리지와 큰 차이가 없는 수준 이내에서 성능 향상이 가능하다. NVMe가 워낙 빨라서 CPU가 성능을 뽑아내지 못하는 상황이 오고 있음.

Advertisements
Posted in 1) Memo

Protected: 20170925 – Research

This content is password protected. To view it please enter your password below:

Posted in 1) Memo

Protected: 20170924 – Research

This content is password protected. To view it please enter your password below:

Posted in 1) Memo

Protected: 20170922 – Research

This content is password protected. To view it please enter your password below:

Posted in 1) Memo

20170921

병렬처리
오늘은 vDNN 논문에 대해 이야기할 것. 뉴럴 넷은 데이터를 가지고 weight를 학습한다는 것이 장점이다. 이러한 weight들을 학습시키는 방법 중 하나가 stochastic gradient descent. Loss function을 최소화하는 방식으로 weight를 학습시킨다. Convolution layer는 forward / backward path 모두 convolution 연산이다. Convolution을 행렬곱으로 하면 메모리 사용량은 적지만 시간이 오래걸림, FFT로 하면 메모리 사용량은 많지만 시간이 적게 걸림. vDNN 논문에서는 FFT 사용 위한 메모리를 workspace라고 이야기함. NVprofiler를 사용하면 GPU의 자원 사용량을 알 수 있다. 특정 연산 시점을 기준으로 profiling하면 레이어 당 메모리 사용량을 알 수 있을 것. 뉴럴 넷 학습에서 대부분의 메모리 할당이 feature map에서 발생한다. weight는 상당히 적은 부분(feature maps > gradients > weights). vDNN 논문의 핵심은 GPU 메모리 부족을 CPU 메모리를 사용으로 해결하자. 그리고 이 때 뉴럴 넷 학습의 특징을 활용하자. 뉴럴 넷 학습에서 feature map은 backward path에서도 필요하다. 따라서 메모리에 계속해서 올려둘 필요 없이, 해당 시점에 올려도 된다. 중요한 가정이 있는데, 데이터 연산 속도가 데이터 이동 속도보다 느리다는 것. vDNN에서는 stream을 사용해 메모리의 offloading과 prefetching을 하도록 함.

Posted in 1) Memo

Protected: 20170920 – Research

This content is password protected. To view it please enter your password below:

Posted in 1) Memo

20170919

1. 병렬 처리
GPU에서 행렬 접근시 column-wise 접근이 coalescing에 더 좋음. Thread 내에서는 locality가 낮지만, thread 사이에는 locality가 높아 coalescing이 쉬움.
shared memory도 여러 개의 bank로 나누어져 있고, 따라서 bank conflict가 없도록 접근할 때 최대 성능을 보인다.
CHWN/NCHW 등의 메모리 배치에 따른 성능이 다르고, 이는 coalescing 때문이다. Memory access pattern에 차이가 발생한다.


2. 운동
오늘은 덤벨 쓰러스터와 TRX 로우를 배움. TRX 로우를 할 때에는 반동을 주지 말고, 천천히 올라갔다 내려가야 한다.

Posted in 1) Memo
누적 방문자 수
  • 96,546 hits