totalrecall
138
2021-06-11 18:22:05
11
118

Visual C++에서 병렬 프로그래밍 어떻게 하는지요?


안녕하십니까?


저의 질문을 정확히 말씀 드리면요


윈도우10에서

D:\image 라는 폴더에 100만개의 jpg 파일이 있다고 할 경우

이 jpg들을 각각 png로 변환하는 프로그램을 만든다고 할 경우에요


100만개의 jpg 파일들을

10개의 부분 집합으로 나눈 다음에 (10만개씩)

각각의 부분집합에 대해 png로 변환하는 작업을 하고 싶습니다


이 작업을 10개의 부분집합에 대해 동시에 진행하고 싶습니다


목적은 수행 시간을 단축하는 것입니다


요즘 CPU는 보통 6코어 이상 하므로, 이런 작업을 하기에 적합할 거 같은데요


이렇게 CPU 멀티코어를 이용해서 병렬 작업(?)을 하려면


어떤 코딩 방식을 하는 것이 가장 바람직한지 조언을 부탁 드립니다


혹시 C++보다 C#이나 Java, Python, Julia 등이 이런 일을 더 잘한다면

추천 부탁 드립니다


감사합니다

0
  • 답변 11

  • 그래안그래
    627
    2021-06-11 18:59:36

    쓰레드

  • totalrecall
    138
    2021-06-11 19:16:44

    쓰레드 방식이 낫나요

    아니면 아에 멀티 프로세스 방식이 나을까요

  • 캐티
    3k
    2021-06-11 19:17:14
  • 해리아범
    260
    2021-06-11 19:27:24

    적어주신 내용만으로는 프로그래밍이 필요없이 그냥 있는 프로그램 구해다 돌리는 게 나을 것 같은데요

    Bulk image converter나 multiple image converter로 구글링하시면 많이 나올거예요

  • totalrecall
    138
    2021-06-11 19:42:28
    캐티님... 감사 드립니다^^ 나중에 내용을 찬찬히 공부해 보겠습니다
  • totalrecall
    138
    2021-06-11 19:43:13

    해리아범님..본문에서 든 png변환은 하나의 예입니다

    본문과 같은 코딩에서 속도 개선을 하고 싶은 것입니다

  • 그래안그래
    627
    2021-06-11 20:37:10

    쿠다프로그래밍으로 gpu를 이용한 병렬성능을 극대화시키는방법도있을것같습니다.

  • Hide_D
    682
    2021-06-12 01:45:47 작성 2021-06-12 02:11:51 수정됨

    스레드 써야할 일 생기면 요샌 그냥 rust가 더 낫지 않나 싶긴 한데

    저는 C++17 언어 모드에서 thread_pool 구현들 가져다 쓰는 편입니다.


    https://github.com/bshoshany/thread-pool


    여기의 스레드 풀을 이용하면 대충 아래처럼 만들어 쓸 수 있어요.



    #define _CRT_SECURE_NO_WARNINGS
    
    #include <cstdio>
    #include "thread_pool.hpp"
    #include <deque>
    #include <string>
    
    thread_pool pool; //코어 수를 적지 않았다면 스레드 수만큼 잡아 주는게 일반적 
    using namespace std;
    
    int main(int, char**) {
        size_t work_cnt = 1000; //할 일 리스트 
        deque<future<string>> jobs; 
    
        for(size_t i = 0; i < work_cnt; i++){
            jobs.push_back(pool.submit([i]{
                printf("Do %zu task!\n", i);
    
                // task 수행(data race 없는 작업 추천) 
                char buff[20];
                sprintf(buff, "Done %zu task!", i);
    
                //적당히 시간이 걸린다고 가정. 숫자에 딱히 의미는 없음 
                std::this_thread::sleep_for(std::chrono::milliseconds((i*293)%443));
    
                // 결과 반환
                return string(buff);
            }));
        }
        
        while(!jobs.empty()){
            string text = jobs.front().get(); //move semantics로 작동하므로 get은 딱 한번만. 
            printf("%s\n", text.c_str());
            jobs.pop_front();
        }
        printf("done!\n");
        return 0;
    }
    


    C++17 은 아주 편리하게 위쪽에서 submit 하고 연산 결과를 아래에 get으로 받아올 수 있는데, 이걸 쓰려면 Visual Studio 2019 (+ C++17 지원하는 버전으로 업데이트)가 필요하구요.

    그게 아니면 C++11 까지 지원하는 thread_pool 로 결과값을 받아오려면 mutex 하나를 따로 만들어 관리해야해서 좀 귀찮습니다.

  • totalrecall
    138
    2021-06-14 14:55:31

    Hide_D 님, 상세한 설명 감사 드립니다^^

    C++17을 사용하면 되겠네요

    적극 활용해 보겠습니다

    즐거운 하루 되시고 다음에 또 뵙겠습니다

  • Hide_D
    682
    2021-06-14 15:27:43

    totalrecall 도움이 되었다면 다행이네요.


    참고로 위에 제시한 thread_pool 방법은 스레드를 효율적으로 처리하기 때문에

    100만개를 10개로 나눈다거나 할 필요없이 그냥 100만개 밀어넣어도 잘 동작합니다.

  • totalrecall
    138
    2021-06-15 09:29:58

    네, 설명 감사 드립니다^^

    잘 이해 되었습니다

    다음에 또 뵙겠습니다

  • 로그인을 하시면 답변을 등록할 수 있습니다.