반응형

강좌 17

C++ 코루틴(coroutine) 활용 강좌: #4 : co_yield

이번 강좌는 co_yield 이용하여 값을 생산하면서 제어권을 다른 쪽으로 넘기는 예제를 살펴보도록 하겠습니다. 코루틴 상태 관련 객체로 cotask_enumarator을 정의하여 사용합니다. 구체적으로 값을 생산하는 함수A 예를 살펴보도록 하겠습니다. 이 예제는 Unity 등 C#에서 많이 쓰는 IEnumerator를 리턴하는 함수와 같은 cotask_func_enum 함수를 정의하고 있습니다. 이 예제는 C#에서 많이 쓰는 코루틴 기법을 C++에서 사용하는 법을 보여주고 있습니다. 예제 코드는 아래와 같습니다. #include #include #include #include #include #include using namespace std; template struct cotask_enumarato..

강좌 2022.05.24

C++ 코루틴(coroutine) 활용 강좌: #3 : co_return

이번 강좌는 co_await를 이용하여 함수 중간에 제어권을 다른 쪽으로 넘기다가 코루틴 함수의 끝에 co_return으로 값을 리턴하는 예제를 살펴보도록 하겠습니다. 예제는 실행 중간에 실행권을 멈추고 제어권을 다른 쪽으로 넘기면서 실행되다가 코루팀 함수의 끝에 값을 co_return으로 리턴하고 종료하는 코루틴 함수 A와 B를 보여주고 있습니다. C++ 코루틴(coroutine) 활용 강좌: #2 : co_await의 예제와 내용이 비슷한데 co_return으로 값을 리턴하고 코루틴 함수가 종료된다는 것만 틀립니다. 예제 코드는 아래와 같습니다. #include #include #include #include using namespace std; template struct cotask_return ..

강좌 2022.05.23

C++ 코루틴(coroutine) 활용 강좌: #2 : co_await

이번 강좌는 c++ coroutine의 기본적인 사용법과 co_await를 이용하여 함수 중간에 제어권을 다른 쪽으로 넘기는 것을 살펴보도록 하겠습니다. 구체적으로 실행 중간에 실행권을 멈추고 제어권을 다른 쪽으로 넘기면서 실행되는 함수 A와 B의 예를 살펴보도록 하겠습니다. 예제는 Win32의 Fiber를 사용하는 것과 비슷하게 느껴질 것입니다. 예제 코드는 아래와 같습니다. #include #include #include #include using namespace std; struct cotask_noreturn { struct promise_type; using handle_type = std::coroutine_handle; struct promise_type { std::exception_pt..

강좌 2022.05.20

C++ 코루틴(coroutine) 활용 강좌: #1 시작하며 그리고 기본 개념

코루틴이라는 것이 개념적으로는 쉬운 내용이고 C#과 같은 다른 언어에서는 언어의 기본 구현에 포함되어 간편하게 사용할 수 있습니다. 하지만 C++은 늦게 C++ 20 표준에 포함되었고 구현이 조금은 투박하게 느껴지는 관계로 사용하는게 쉽지는 않습니다. 이런 이유로 코루틴의 활용보다는 코루틴 사용을 위한 기반 내용에 초점이 맞추어져 있는 기존 글들과는 달리 활용에 맞추어 강좌를 만들었습니다. 이 강좌 시리즈에서는 표준에 맞게 C++로 구현한 코루틴 관련 상태 객체 소스를 바탕으로 실제로 코루틴을 사용하는 활용 예제를 살펴보도록 하겠습니다. C++ 표준에서 코루틴을 사용하기 위하여 직접 구현해야 하는 것 중 하나가 코루틴 관련 상태 객체인데 이 부분은 예제 소스로 제공하도록 하겠습니다. 실제로 자신의 프로젝..

강좌 2022.05.19

C++ REST API 사용 강좌 : #2 HTTP POST (boost beast 활용)

이번에는 C++ boost beast를 활용하여 JSON을 인자로 REST API을 호출하여 데이터를 받는 예제를 살펴보도록 하겠습니다. 이 강좌는 C++ REST API 사용 강좌 : #1 HTTP GET (boost beast 활용)에서 이러지는 강좌로 설명 소스가 비슷한 관계로 해당 글에서 설명한 내용(UTF-8, 비동기 처리 등)은 이 글에 없는 관계로 해당 글도 꼭 참고 부탁드립니다. 이번에 살펴볼 소스는 아래와 같습니다. #include #include #include #include #include #include using namespace std; int main(int argc, char* argv[]) { boost::asio::io_context ioc; boost::asio::ip..

강좌 2022.05.12

C++ REST API 사용 강좌 : #1 HTTP GET (boost beast 활용)

근래에는 TCP/IP로 바로 통신하는 프로그램보다는 REST API를 이용하여 통신하는 프로그램이 대세인 듯 보입니다. 여기서는 C++로 REST API를 사용하는 방법을 알아보도록 하겠습니다. 강좌는 boost를 사용하였으며 boost에서 HTTP 통신 관련 상위 라이브러리인 boost beast를 사용합니다. REST API의 기본이 되는 GET 메소드를 이용하여 데이터를 가져오는 방법을 살펴보겠습니다. GET 메소드를 이용하여 데이터를 가져오는 소스는 아래와 같습니다. 소스를 보면서 계속 설명하겠습니다. #include #include #include #include #include #include using namespace std; int main(int argc, char* argv[]) { ..

강좌 2022.05.11

C++ boost 메모리풀 강좌 #5: boost 메모리풀 할당자를 적용하여 STL 컬렉션의 성능 향상시키기

STL 컬렉션은 템플릿 지정자를 이용하여 메모리 할당자를 설정할 수 있습니다. 참고로 메모리 할당자란 컬렉션에 요소에 대해서 메모리 new / delete하는 객체를 말합니다. STL 컬렉션에 메모리 할당자를 메모리풀을 사용하도록 하여 성능을 향상 시킬 수 있습니다. boost에는 이 STL 컬렉션 관련 메모리 풀 지원 할당자가 pool_allocator와 fast_pool_allocator이 있습니다. 두 할당자 모두 어느 STL 컬렉션에나 사용할 수 있습니다. 특징적으로 pool_allocator는 vector처럼 연속된 메모리 할당 및 해제가 일어나는 STL 컬렉션에서 성능이 좋습니다. fast_pool_allocator는 list처럼 단일 메모리 할당 및 해제가 일어나는 STL 컬렉션에서 성능이 ..

강좌 2021.11.15

C++ boost 메모리풀 강좌 #4: object_pool 클래스를 이용하여 new 재정의 없이 일반 클래스에 메모리풀 적용하기

object_pool은 pool의 클래스 할당 및 해제 버전으로 보면 이해하기 쉽습니다. pool과 사용법이 유사한데 틀린점은 construct와 destory 함수를 이용하여 할당 및 해제를 한다는 점입니다. 또한 construct 함수를 호출할 때 생성 인자를 넣어서 생성할 수도 있습니다. 단, 아쉽게도 생성인자는 3개까지 지원합니다. new 재정의로 메모리 풀을 적용하지 않은 클래스에 대하여 생성시점에서 메모리풀을 사용하기에 좋습니다. 간단한 예를 살펴보도록 하겠습니다. #include #include using namespace std; class test_mpa2 { private: char test_[256]; public: test_mpa2(const char* str) { strcpy_s(..

강좌 2021.11.14

C++ boost 메모리풀 강좌 #3: singleton_pool 클래스를 이용하여 일반 클래스에 메모리풀 적용하기

singleton_pool 클래스도 기본적으로 이전에 설명한 pool과 비슷합니다. 이 클래스는 템플릿 주요 인자로 할당 크기를 구분하는 태그 인자와 할당 크기를 받습니다. 태크 인자와 할당 크기라는 인자 특성 때문에 일반 클래스에 operator new / delete를 재정하여 적용하기에 쉽습니다. 이 외에 singleton_pool은 기본적으로 멀티쓰레드에서 안전합니다. 싱글쓰레드에서 사용할 때는 성능을 올리기 위하여 mutex 인자 부분에 boost::details::pool::null_mutex을 넣어주면 좋습니다. 간단한 사용법 예를 살펴보겠습니다. #include #include using namespace std; template class memory_pool_allo..

강좌 2021.11.13

C++ boost 메모리풀 강좌 #2: pool 클래스를 이용하여 버퍼에 메모리풀 적용하기

boost 메모리풀 관련 클래스 중 pool은 메모리풀을 활용하여 C 스타일로 메모리를 할당 및 해제할 때 사용할 수 있는 클래스입니다. 이런 특성을 가진 관계로 C++에서 C스타일로 메모리를 할당 및 해제하는 버퍼에 적용하기 좋습니다. 이 클래스를 버퍼에 활용하면 메모리풀이 적용되어 성능 향상에 좋습니다. 간단히 아래 예제를 통하여 살펴보겠습니다. #include #include using namespace std; int main(int argc, char* argv[]) { boost::pool pool(sizeof(char) * 32); char* test = (char*)pool.malloc(); strcpy_s(test, sizeof(char) * 32, "test test test test"..

강좌 2021.11.12

C++ boost 메모리풀 강좌 #1: 메모리풀의 개념

메모리 풀은 미리 메모리를 할당하여 놓은 뒤 필요에 따라 할당 및 해제하여 사용하는 기법을 의미합니다. 메모리 풀은 아래와 같은 이점이 있습니다. 첫번째로 할당과 해제에 따른 성능의 향상이 있습니다. 이유는 메모리 할당과 해제 관련 함수는 실제적으로 OS로 부터 메모리를 가져오거나 할당과 해제 관련 메모리 관리처리를 하기 때문에 상대적으로 적은 양이지만 오버헤드가 있기 때문입니다. 두번째로 메모리 단편화가 줄어듭니다. 이유는 미리 상대적으로 큰 메모리를 할당한 뒤 사용하기 때문에 상대적으로 작은 메모리의 할당과 해제에 따른 메모리 단편화가 발생할 가능성이 줄어들기 때문입니다. 메모리 풀은 다음과 같은 단점이 있습니다. 첫번째로 메모리 사용 효율성이 떨어질 수 있습니다. 이유는 미리 상대적으로 큰 메모리를..

강좌 2021.11.11

병렬처리 개념 강좌: #6 설계 관련 팁

병렬 처리를 설계할 때 생각해 보면 좋은 것들은 아래와 같습니다. 병렬적으로 처리될 수 있도록 프로그램을 설계합니다. 프로그램에 따라서 단일 처리를 병렬 처리를 하기 위해서는 단순히 API를 사용하는 것 이상으로 프로그램 디자인 형태가 병렬 처리에 적합해야 하고 때때로 병렬처리를 위하여 수정해야할 수도 있습니다. 처음 디자인시 병렬 처리에 적합하도록 설계하면 좋습니다. 쓰레드를 고려하지 않고 단일 쓰레드 환경에서 작업 태스크 중심으로 설계를 합니다. 병렬처리는 앞에 설명한 대로 크게 2가지의 처리 형태를 가집니다. 멀티 쓰레드 사용 형태 보다는 이 CPU 관련 작업의 성능 향상을 할 수 있는 2가지 형태에 적합하도록 설계하는 것이 좋습니다. 로직의 디버깅을 위하여 병렬처리 뿐만 아니 단일처리에서도 동작하..

강좌 2021.11.09

병렬처리 개념 강좌: #5 설계 관련 3가지 생각 포인트

병렬처리 설계를 할 때 살펴보아야 할 3가지 포인트가 있습니다. 1. 확장성(Scaling) 코어 개수의 변화에 따라 성능이 더욱 좋아지도록 설계를 하여야 합니다. 데이터 병렬처리에서 100개의 데이터를 처리한다고 하였을 때 코어가 2개일 때는 각각 50개씩, 코어가 4개일 때는 각각 25개씩 처리할 수 있게 설계하는 것 같은 것이 좋은 예일 것입니다. 2. 적절성(Correctness) 병렬 처리를 통한 성능 향상에 최적화되도록 설계를 하여야 합니다. 병렬처리 프로그래밍은 멀티 쓰레드가 동시에 한 자원에 접근하였을 때 발생하는 동기화 문제가 발생할 수 있습니다. 또한 데드락 문제도 발생할 수 있습니다. 이는 멀티 쓰레드의 개별 쓰레드처럼 병렬 처리의 각각의 쓰레드도 처리를 위하여 자원을 사용하기 때문입..

강좌 2021.11.08

병렬처리 개념 강좌: #4 2가지 종류의 병렬처리

병렬처리는 사용 개념적으로 보았을 때 크게 데이터 처리 기반 병렬처리와 태스크 처리 기반 병렬처리로 나누어 질 수 있습니다. 데이터 처리 기반 병렬 처리(Data Parallelism) 큰 데이터를 분할하여 여러 개의 프로세스가 처리하는 것을 말합니다. 간단히 4개 코어를 기반으로 100개의 데이터를 처리한다고 하였을 때 1~25, 26~50, 51~75, 76~100 이렇게 데이터를 나누어서 4개의 코어가 각각 처리하는 것을 예로 들 수 있습니다. 이렇게 처리하면 데이터를 처리하는 부분은 이론적으로 N배의 성능 향상을 가져올 수 있습니다. 태스크 처리 기반 병렬 처리(Task Parallelism) 여러 개의 작업을 각각의 프로세스에게 분배하여 다중 처리하는 것을 의미합니다. 3개의 코어가 3개의 함수..

강좌 2021.11.07
반응형