반응형
반응형

1.async

  • 사용 예시
// async : 즉시 실행
auto a1 = std::async(std::launch::async, foo); // 이 때 스레드 실행
std::cout<<a1.get();

//deferred : 리턴값을 받아올 때 실행
auto a1 = std::async(std::launch::deferred, foo);
std::cout<<a1.get(); // 이 때 스레드 실행
  1. 정책

    • async : 새로운 스레드를 즉시 실행
    • deferred : 리턴값을 받아올 때 실행
  2. thread와의 차이점

    • 직접 스레드를 관리(생성, 삭제) 하지 않음
    • 함수에서 던진 예외에 대해 예외처리 가능
    • oversubscription
      • 스레드는 너무 많은 스레드 만들면 중단
      • 내부적으로 task관리해주기 때문에 중단 없음
    • 스레드를 직접 만들지 않고 스레드 풀 이용
    • 반환값을 받을 수 있다.
future<int> a1 = async(launch::async, foo);
const int ret = a1.get();

2.OpenMP

  1. 병렬 프로그래밍을 쉽게 할 수 있게 제공하는 API
  2. 사용 방법
    • 헤더 추가 : omp.h
    • 사용 : 부하가 많은 곳 위에 명령 입력
      #pragma omp parallel for
    • fork and join 모델로 컴파일 됨
    • 코어 개수 만큼 스레드 생성
#include <omp.h>
void main(){
   int a[1000];
   int b[1000];
   int c[1000];

   #pragma omp parallel for
   for(int i=0; i< 1000 ; i++){
      c[i] = a[i] + b[i];
   }
}
  1. 옵션
    • 위의 구문 뒤에 옵션 추가 가능

1)schedule(dynamic,1) 옵션

  • 1 = chuncksize, defualt = 1
  • chuncksize 개수만큼 배열을 태크스로 나누고, 코어 개수 만큼 스레드 런칭
  • dynamic하게 태스크를 수행하여, 먼저 끝난 스레드는 다음 태스크를 수행
  • static 옵션은 스레드가 수행할 태크스를 미리 정하고 끝나면 기다리므로 비효율적

참고

코드없는 프로그래밍(유투브)

3.CUDA

  1. 개발 순서
    • 커널(함수) 선언
    • 변수를 할당(cudaMalloc)
    • 변수를 복사(cudaMemcpy)
    • 동작 수행
    • 결과 변수를 복사(cudaMemcpy)
    • 변수 메모리 해제(cudaFree)
__global__
void add(int n, float *x, float *y, float *z){
   int i = blcokIdx.x * blockDim.x + threadIdx.x;
   if( i < n){
      z[i] = x[i] + y[i];
   }
}
void main(){
   int N = 100000;
   std::vector<float> x(N);
   std::vector<float> y(N);
   std::vector<float> z(N);

   float * d_x, *d_y, *d_z;
   cudaMalloc(&d_x, N*sizeof(float));
   cudaMalloc(&d_y, N*sizeof(float));
   cudaMalloc(&d_z, N*sizeof(float));

   cudaMemcpy(d_x, x.data(), N*sizeof(float), cudaMemcpyHostToDevice);
   cudaMemcpy(d_y, y.data(), N*sizeof(float), cudaMemcpyHostToDevice);

   add<<<(N+255)/256, 256>>>(N, d_x, d_y, d_z);

   cudaMemCpy(z.data(), d_z, N*sizeof*float), cudaMemcpyDeviceToHost);

   cudaFree(d_x);
   cudaFree(d_y);
   cudaFree(d_z);
}

4. thread에서 메모리 맵

  1. 로컬 변수(스택 공간)는 각 스레드에 종속적
  2. 힙과 static 공간은 공유함
    • race condition 발생 가능

5.false sharing

  1. 병렬 프로그래밍이 더 느릴 수 있다.
  2. 원인
    • 멀티 코어 환경에서 각 코어에서 접근하고 있는 데이터가 같은 캐시라인에 있을 때 발생
    • 실제 공유 데이터가 아님에도 하드웨어에서는 공유하는 것으로 착각
    • 동기화가 발생하여 속도가 저하됨
  3. 해결 방법

6. condition variable

  1. 한 스레드에서 다른 쓰레드로 신호를 보냄
  2. 신호를 받은 쓰레드는 컨디션 밸류를 체크하고 동작 수행
  3. 컨디션 밸류는 두 쓰레드에서 쓰기 때문에 뮤텍스 필수!
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
int condition = 0;

void foo(){
   std::unique_lock<std::mutex> lock(m);
   cv.wait(lock, []{return condition==1;})
//lock is acquired, mutual exc job
   lock.unlock();
   // do rest jobs;
}
int main(){
   std::thread waitngT(foo);
   {
      std::scoped_lock lock(m);
      condition = 1;
   }
   cv.notify_one();
   waitngT.join();
}

참고

코드없는 프로그래밍(유투브)

반응형

'C++ > C++' 카테고리의 다른 글

[C++] 함수형 프로그래밍  (0) 2021.03.11
[C++]스마트 포인터  (0) 2021.03.09
[C++]LR value 및 최적화  (0) 2021.03.09
[C++]빌드 프로세스  (0) 2021.03.09
[C++]메모리 구조  (0) 2021.03.09

+ Recent posts

반응형