직관적인느낌

TBB(Threading Building Blocks)와 concurrent_queue/concurrent_vector [+일반 컨테이너] 본문

공학

TBB(Threading Building Blocks)와 concurrent_queue/concurrent_vector [+일반 컨테이너]

범슐랭 2024. 1. 9. 07:36
728x90
반응형

TBB(Threading Building Blocks)는 C++을 위한 병렬 프로그래밍 라이브러리로, Intel에서 개발하였습니다. 

TBB는 고성능 컴퓨팅을 위한 병렬 알고리즘, 병렬 태스크, 동기화 프리미티브, 메모리 할당 등을 제공합니다.

TBB는 효율적인 멀티코어 프로그래밍을 위해 고안되었으며, 
개발자가 직접 스레드를 관리하는 대신 고수준의 추상화를 제공함으로써 병렬 프로그래밍을 간소화합니다. 
또한, TBB는 동적 스케줄링을 사용하여 태스크를 코어에 분배하므로, 높은 성능과 확장성을 달성할 수 있습니다.



TBB의 concurrent_queueconcurrent_vector에 대해 설명하겠습니다.

concurrent_queue:
TBB의 concurrent_queue는 여러 스레드에서 동시에 안전하게 접근할 수 있는 FIFO(First In, First Out) 데이터 구조입니다. std::queue와 비슷하지만, 여러 스레드에서 동시에 요소를 추가하거나 제거할 수 있습니다.
이는 내부적으로 뮤텍스 또는 비슷한 동기화 메커니즘을 사용하여 동시 접근을 관리합니다.


concurrent_vector: 
TBB의 concurrent_vector는 std::vector와 비슷한 동적 배열을 제공하지만, 여러 스레드에서 동시에 안전하게 접근할 수 있습니다. 
concurrent_vector는 요소를 추가하는 연산을 여러 스레드에서 동시에 수행할 수 있습니다
그러나 요소를 제거하거나 벡터의 크기를 줄이는 연산은 동시에 수행할 수 없습니다.
이러한 concurrent 컨테이너는 멀티스레드 환경에서 공유 데이터를 안전하게 관리하는 데 매우 유용합니다. 
하지만 동기화에는 비용이 들기 때문에, 단일 스레드 환경에서는 일반 컨테이너를 사용하는 것이 더 효율적일 수 있습니다.


  • 일반 컨테이너
    • 일반적으로 단일 스레드 환경에서 사용되는 데이터 구조를 참조합니다.
      이들 컨테이너는 C++ 표준 라이브러리(STL, Standard Template Library)의 일부로 제공되며,
      병렬 처리나 동기화 기능을 내장하고 있지 않습니다.

      일반 컨테이너의 예로는 다음과 같은 것들이 있습니다:

      - std::vector:
      동적 배열로, 요소를 추가하거나 제거함으로써 크기를 동적으로 변경할 수 있습니다. 
      랜덤 액세스가 가능하므로 인덱스를 사용하여 요소에 빠르게 접근할 수 있습니다.

      - std::list:
      이중 연결 리스트로, 요소를 추가하거나 제거하는데 필요한 작업이 상수 시간에 이루어집니다.
      그러나 랜덤 액세스는 지원하지 않으며, 메모리 사용이 상대적으로 높습니다.

      - std::deque:
      양쪽 끝에서 요소를 추가하거나 제거하는데 효율적인 덱(deck) 데이터 구조입니다.
      랜덤 액세스가 가능합니다.

      - std::map / std::unordered_map:
      키-값 쌍을 저장하는 맵(map) 데이터 구조로, 키를 기반으로 값을 빠르게 검색할 수 있습니다.
      std::map은 키를 정렬된 상태로 유지하지만, std::unordered_map은 정렬하지 않습니다.

      - std::set / std::unordered_set:
      중복 없이 요소를 저장하는 셋(set) 데이터 구조로, 특정 요소가 존재하는지 빠르게 확인할 수 있습니다.
      std::set은 요소를 정렬된 상태로 유지하지만, std::unordered_set은 정렬하지 않습니다.

      이러한 일반 컨테이너는 단일 스레드 환경에서 효율적으로 작동하지만, 멀티스레드 환경에서는 동기화 메커니즘을 추가적으로 사용해야 할 수 있습니다. 이 경우, TBB와 같은 병렬 프로그래밍 라이브러리에서 제공하는 concurrent 컨테이너를 사용하는 것이 좋을 수 있습니다.

  • concurrent 컨테이너
    • 멀티스레드 환경에서 여러 스레드가 동시에 접근하고 수정할 수 있도록 설계된 데이터 구조를 의미합니다. 
      이러한 컨테이너는 내부적으로 동기화 메커니즘을 사용하여 데이터 경쟁 상황을 방지하며, 일반적으로 병렬 프로그래밍 라이브러리에서 제공됩니다.

      일반 컨테이너와 달리 concurrent 컨테이너는 여러 스레드에서 동시에 안전하게 사용할 수 있습니다. 
      그러나 이러한 동기화는 추가적인 처리 시간을 필요로 하므로, 단일 스레드 환경에서는 일반 컨테이너를 사용하는 것이 더 효율적일 수 있습니다.

      여러 종류의 concurrent 컨테이너가 있지만, 대표적인 예로는 다음과 같은 것들이 있습니다:

      - Concurrent Queue:
      여러 스레드에서 동시에 요소를 추가하거나 제거할 수 있는 FIFO(First In, First Out) 데이터 구조.
      예를 들어, Intel의 Threading Building Blocks(TBB) 라이브러리에는 "concurrent_queue"가 있습니다.

      - Concurrent Vector:
      여러 스레드에서 동시에 요소를 추가할 수 있는 동적 배열.
      요소의 제거나 크기 변경은 일반적으로 동시에 수행할 수 없습니다.
      TBB 라이브러리의 "concurrent_vector"가 이에 해당합니다.

      - Concurrent Hash Map:
      여러 스레드에서 동시에 키-값 쌍을 추가, 검색, 제거할 수 있는 해시 맵.
      Java의 "ConcurrentHashMap"이나 TBB의 "concurrent_hash_map"이 이에 해당합니다.

      각 concurrent 컨테이너는 그 자체의 특성과 사용 사례에 따라 선택되어야 합니다. 
      예를 들어, 
      여러 스레드가 동시에 요소를 추가해야 하는 경우에는 concurrent vector를, 
      여러 스레드가 동시에 요소를 추가하거나 제거해야 하는 경우에는 concurrent queue를 선택할 수 있습니다.

  • 병렬 알고리즘
  • 병렬 태스크
  • 동기화 프리미티브
  • 메모리 할당
728x90
반응형

'공학' 카테고리의 다른 글

OpenMP[Open Multi-Processing]  (0) 2024.01.10
Eigen과 Sophus  (0) 2024.01.10
std::mutex 와 lock/unlock  (0) 2024.01.09
std:: vector와 힙/스택/큐  (0) 2024.01.09
Github 코드 수정 및 branch 생성  (0) 2023.03.25