SLAM Engineer

๐ŸŒˆ C++17 execution ์‹ค์Šต 1ํŽธ: ๋นŒ๋“œ๋ถ€ํ„ฐ ์‹คํ–‰๊นŒ์ง€ (Feat. oneTBB and g++-11)


๋„์ปค ๋นŒ๋“œ๋ถ€ํ„ฐ ๋– ๋จน์—ฌ์ฃผ๋Š” ๊ฐ•์˜

  • ๋ฏธ๋ž˜์˜ ๋‚˜๋ฅผ ์œ„ํ•ด
  • ๊นŒ๋จน๋Š”๋‹ค.

C++17 execution ์ด๋ž€?

  • C++์˜ ํ‘œ์ค€์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ policy (seq, unseq, par, par_unseq ์ค‘ ํ•˜๋‚˜) ์ง€์ •ํ•ด์ฃผ๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์•Œ์•„์„œ ๋ฉ€ํ‹ฐ์ฝ”์–ด๋ฅผ ํ™œ์šฉํ•˜๋Š” ์‹คํ–‰ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๋ฌธ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค.
  • ์ž์„ธํ•œ ์„ค๋ช…์€ ์›น์— ๋งŽ์œผ๋‹ˆ ์ƒ๋žตํ•œ๋‹ค.
  • ๋Œ€์‹  ์ง์ ‘ ์‹คํ—˜ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์—ฐ๋งํœด๊ฐ€๊ธฐ๋ก.

์‹ค์Šต

  • ๋ƒ…๋‹ค ์‹ค์Šตํ•ด๋ณด์ž.
  • ์ฐจ๋ก€๋Œ€๋กœ ์•Œ์•„๋ณด์ž.

1. ๋ชจ๋“  ์‹ค์Šต์˜ ์‹œ์ž‘์€ ๋„์ปค์ด๋ฏธ์ง€ ๊ตฝ๊ธฐ ๋ถ€ํ„ฐ

  • ํ›„์ˆ ํ•˜๊ฒ ์ง€๋งŒ gcc version ์— ๋”ฐ๋ผ ๋นŒ๋“œ๊ฐ€ ๋˜๊ธฐ๋„ ์•ˆ๋˜๊ธฐ๋„ ํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์‹ค์Šต์˜ ๊ธฐ๋ณธ์€ ํ™˜๊ฒฝ ๊ฒฉ๋ฆฌ๋ฅผ ์„ ํ˜ธํ•˜๋„๋ก ํ•˜์ž.
  • ๋„์ปค๋ฅผ ํ™œ์šฉํ•˜์ž.
    • ๋„์ปค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.
  • Dockerfile.22.04 ์ด๋ž€ ์ด๋ฆ„์˜ ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž…๋ ฅํ•˜์ž.
    • ps. ํ™•์žฅ์ž๋Š” ์žˆ์–ด๋„ ๋˜๊ณ  ์—†์–ด๋„ ๋œ๋‹ค. Dockerfile ์ด๋ผ๊ณ  ๋ฌดํ™•์žฅ์ž๋กœ ์ด๋ฆ„์ง“๋Š” ๊ฒŒ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ทœ์น™์ด์ง€๋งŒ ๋ง˜๋Œ€๋กœ ์ง€์–ด๋„ ์ƒ๊ด€์—†๋‹ค.
        FROM ubuntu:22.04
      
        # ํ•„์ˆ˜ ํŒจํ‚ค์ง€ ์„ค์น˜
            RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
            build-essential \
            g++ \
            cmake \
            git
      
        # ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ •
        WORKDIR /usr/src/myapp
      
      • ์ถ”ํ›„์— ๋ช‡ ๊ฐ€์ง€ ํ•„์š”ํ•œ ๊ฒƒ์„ ๋” ์„ค์น˜ํ•  ์˜ˆ์ •์ด๋‹ค.
        • ๊ทธ๊ฒƒ๋“ค์„ ์›๋ž˜ Dockerfile ์•ˆ์— ๋ชจ๋‘ ๊ธฐ์ž…ํ•˜์—ฌ ์›์ƒท์œผ๋กœ ๋” ํŽธํ•˜๊ฒŒ ํ•˜๋ฉด ์ข‹๊ฒ ์ง€๋งŒ
        • ์Šคํ…๋ฐ”์ด์Šคํ…์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์ผ๋‹จ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ๋งŒ ๊ตฌ์› ๋‹ค.
        • ์ด ์ •๋„ ๋ฒ ์ด์Šค๋กœ๋งŒ ๊ตฌ์šฐ๋ฉด ๋นจ๋ฆฌ ๊ตฌ์›Œ์ง€๊ณ  ์šฉ๋Ÿ‰๋„ ์ž‘์•„์„œ ์ข‹๋‹ค. ์ด๋ฒˆ ์‹คํ—˜์™ธ์— ํ‰์†Œ์—๋„ ๋‹ค์–‘ํ•œ ์‹คํ—˜๋“ค์„ ๊นจ๋—ํ•˜๊ฒŒ ์‹œ์ž‘ํ•ด๋ณด๊ณ  ์‹ถ์„ ๋•Œ ๊ณตํ†ต์ ์ธ ๋ฏธ๋‹ˆ๋ฉ€ํ•œ ๋ฒ ์ด์Šค๋กœ ์“ฐ๊ธฐ ์ข‹ ๋‹ค.
    • ๊ทธ๋‚˜์ €๋‚˜ C++ project ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ์—๋Š” ์ž์‹ ์˜ C++ ์ƒํƒœ๊ณ„์— ๋Œ€ํ•ด์„œ๋„ ์ž˜ ์•Œ์•„์•ผ ํ•œ๋‹ค (== C++๋ณด๋‹ค ์ข‹์€ ์–ธ์–ด๊ฐ€ ๋‚˜์™”๋‹ค๊ณ  ํ•ด์„œ ๊ฑฐ๊ธฐ๋กœ ๋ฐ”๋กœ ๊ฐˆ ์ˆ˜ ์—†๋Š” ์ด์œ ).
      • ํŠนํžˆ ํ…์ŠคํŠธ๋ฅผ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฑด ์ปดํŒŒ์ผ๋Ÿฌ(์™€ ๋ง์ปค) ์ธ g++ ์ด๊ธฐ ๋•Œ๋ฌธ์—, g++ ๋ฒ„์ „์ด ๋ช‡์ธ์ง€ ์Šต๊ด€์ ์œผ๋กœ ์ฒดํฌํ•˜๋„๋ก ํ•˜์ž.
        • ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชจ๋“  ๋ฒ„์ „๋“ค์€ ๋””ํดํŠธ ์กฐํ•ฉ๋“ค์ด ์กด์žฌํ•œ๋‹ค.
          • ์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์—์„œ์ฒ˜๋Ÿผ ๊ฐ„๋‹จํžˆ g++ ๋ผ๊ณ  ํ•˜๋ฉด OS ๋ฒ„์ „์— ๋”ฐ๋ผ์„œ ๋””ํดํŠธ ๋ฒ„์ „์„ ์žก๋Š” ๊ฒƒ์ด ๋‹ค๋ฅด๋‹ค.
            • FROM ubuntu:22.04 ํ•  ๊ฒฝ์šฐ (g++ -v ํ•ด๋ณด๋ฉด) ๊ธฐ๋ณธ์ ์œผ๋กœ 11.4๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
            • FROM ubuntu:20.04 ํ•  ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ 9.4๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
  • ํ„ฐ๋ฏธ๋„์—์„œ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ๊ตฌ์›Œ์ง„๋‹ค.
    $ docker buildx build -f ./Dockerfile.22.04 -t cpp-experiment:22.04 .
    
    • ๋งˆ์ง€๋ง‰์— . ์€ Dockerfile.22.04 ์ด๋ž€๊ฒŒ ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.
  • $ docker images๋ผ๊ณ  ํ•˜๋ฉด ๊ตฌ์›Œ์ง„ ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    • ์˜ˆ์‹œ
        REPOSITORY         TAG          IMAGE ID       CREATED         SIZE
        cpp-experiment     22.04        f5621b4b7d84   10 hours ago    1.24GB
      

2. ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๋„์šฐ๊ธฐ

  • docker run ์–ด์ฉŒ๊ตฌ ํ•˜๋ฉด ๋„์ปค ์ด๋ฏธ์ง€๋กœ๋ถ€ํ„ฐ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทผ๋ฐ ๋’ค์— ๋ถ™๋Š” argument๋“ค์„ ๋งค๋ฒˆ ์น˜๋Š” ๊ฒŒ ๊ท€์ฐฎ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋ฆฝํŠธํ™” ํ•˜์ž.
    • ์˜ˆ๋ฅผ ๋“ค์–ด์„œ, run_tbb.22.04.sh๋ผ๊ณ  ํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์จ์ค€๋‹ค.
        echo Using 0 to $1 cores 
      
        docker run -ti --rm \
            --cpuset-cpus="0-$1" \
            --name my-running-app-2204 \
            -v $PWD:/usr/src/myapp \
            cpp-experiment:22.04 \
            bash
      
      • ์ด๋ฒˆ ์‹คํ—˜ (ํ›„์ˆ ) ์—์„œ ์ฝ”์–ด ๊ฐœ์ˆ˜์— ๋”ฐ๋ฅธ ์„ฑ๋Šฅ์ฐจ์ด๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด ์ด๋ ‡๊ฒŒ ํŽธํ•˜๊ฒŒ ๋ฐ›๋„๋ก ํ•˜์˜€๋‹ค. ํ„ฐ๋ฏธ๋„์—์„œ $ ./run_tbb.22.04.sh 5 ์ด๋Ÿฐ์‹์œผ๋กœ ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์ˆซ์ž๋ฅผ ์ค€๋‹ค. 5๋ผ๊ณ  ํ•˜๋ฉด 0๋ฒˆ ์ฝ”์–ด๋ถ€ํ„ฐ 5๋ฒˆ์ฝ”์–ด๊นŒ์ง€ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.
      • docker run ํ•  ๋•Œ --cpuset-cpus ์˜ต์…˜์„ ์ฃผ๋ฉด ์ปจํ…Œ์ด๋„ˆ์— ํ• ๋‹นํ•  ํ˜ธ์ŠคํŠธ CPU๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™˜๊ฒฝ์˜ ๊ฒฉ๋ฆฌ๋ฟ ์•„๋‹ˆ๋ผ ์ž์›์˜ ๊ฒฉ๋ฆฌ๋ฅผ ์„ธํŒ…ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.
    • ๊ทธ๋ž˜์„œ ํ˜„์žฌ ํด๋”์— ์ด๋Ÿฐ๊ฒƒ๋“ค์ด ์žˆ์„ ๋•Œ,
        โ•ฐโ”€$ pwd    
        /home/gskim/Documents/cpp17execution/blog
      
        โ•ฐโ”€$ ls
        Dockerfile.22.04  main.cpp  run_tbb.22.04.sh
      
    • ํ„ฐ๋ฏธ๋„์—์„œ ์ด ์œ„์น˜์—์„œ, $ chmod +x run_tbb.22.04.sh ํ•œ ๋‹ค์Œ์— $ run_tbb.22.04.sh 3 ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด CPU ์ฝ”์–ด ๊ฐœ์ˆ˜๋ฅผ ์ œํ•œํ•˜์—ฌ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ํ„ฐ๋ฏธ๋„ ์†์œผ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
      • ๋„์ปค๋นŒ๋“œํ•  ๋•Œ WORKDIR /usr/src/myapp๋ผ๊ณ  ์ง€์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ํ„ฐ๋ฏธ๋„๋กœ ๋“ค์–ด๊ฐ€๋ฉด ๋ฐ”๋กœ /usr/src/myapp ๋ผ๋Š” ์œ„์น˜์— ์กด์žฌํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ํŽธ์˜์ƒ, -v $PWD:/usr/src/myapp๋ผ๊ณ  ํ•ด์„œ, ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ํ˜„์žฌ ํ˜ธ์ŠคํŠธ์˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋„์ปค์ด๋ฏธ์ง€์˜ /usr/src/myapp ์— ๋งˆ์šดํŠธํ•ด์ฃผ์—ˆ๋‹ค.

3. ๋นŒ๋“œ ๋ฐ ์‹คํ–‰: 1์ฐจ์‹œ๋„

  • ์œ„ ๊ฒฝ๋กœ์— ์žˆ๋Š” ์‹คํ—˜ํŒŒ์ผ์ธ main.cpp๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    • ์ด ์ฝ”๋“œ๋Š” ๋‚ด๊ฐ€ ์ง  ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  cppreference์— ์žˆ๋Š” ๊ฒƒ์„ ๊ฑฐ์˜ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด๋‹ค.
      • ์ด์œ : ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์‹ค์Šต์—๋Š” ํ•ญ์ƒ ๋ณ€์ธ์ด ํ†ต์ œ๋˜๋ฉด ์ข‹๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค (์ฆ‰, ์„ธํŒ…์€ ๋ชจ๋‘ ์ œ๋Œ€๋กœ ํ–ˆ์ง€๋งŒ ๋‚ด๊ฐ€ ์ง์ ‘ ์ง  ์ฝ”๋“œ์— ์กด์žฌํ•˜๋Š” ๊ฒฐํ•จ์œผ๋กœ ๋ณ‘๋ ฌ์‹คํ–‰์‹คํ—˜์ด ์ œ๋Œ€๋กœ ์•ˆ๋  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ).
        #include <algorithm>
        #include <chrono>
        #include <cstdint>
        #include <iostream>
        #include <random>
        #include <string>
        #include <vector>
      
        #ifdef PARALLEL
        // clang-format off
        #include <execution>
        // clang-format on
        namespace execution = std::execution;
        #else
        enum class execution { seq, unseq, par_unseq, par };
        #endif
      
        void measure([[maybe_unused]] auto policy, const std::string policy_name,
                     std::vector<std::uint64_t> v) {
            const auto start = std::chrono::steady_clock::now();
        #ifdef PARALLEL
            std::sort(policy, v.begin(), v.end());
        #else
            std::sort(v.begin(), v.end());
        #endif
            const auto finish = std::chrono::steady_clock::now();
            auto duration =
                std::chrono::duration_cast<std::chrono::milliseconds>(finish - start);
            std::cout << policy_name << ": " << duration.count() << " milliseconds"
                      << std::endl;
        };
      
        int main() {
            std::vector<std::uint64_t> v(1'000'000);
            std::mt19937 gen{std::random_device{}()};
            std::ranges::generate(v, gen);
      
        #ifdef PARALLEL
            measure(execution::seq, "seq      ", v);
            measure(execution::unseq, "unseq    ", v);
            measure(execution::par_unseq, "par_unseq", v);
            measure(execution::par, "par      ", v);
        #else
            measure(execution::seq, "No execution policy", v);
        #endif
      
            return 0;
        }
      
  • ์ผ๋‹จ ๋ชจ๋“  ์ฝ”์–ด๋ฅผ ๋‹ค ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์–ผ๋งˆ๋‚˜ ์„ฑ๋Šฅ์ด๋“์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์ž
    • core 20๊ฐœ ์งœ๋ฆฌ์ธ i7-13700H ์—์„œ ํ…Œ์ŠคํŠธ ํ•˜์˜€๋‹ค.
    • 19 ๋ผ๊ณ  ํ•ด์„œ 0๋ฒˆ๋ถ€ํ„ฐ 19๋ฒˆ ์ฝ”์–ด๊นŒ์ง€ ๋‹ค ํ• ๋‹นํ•ด๋ณด์ž.
        $ run_tbb.22.04.sh 19
      
  1. 1์ฐจ์‹œ๋„-1 (no par)
    • ์ผ๋‹จ ์‹œ๋„1์—์„œ๋Š” ์˜๋„์ ์œผ๋กœ ๋นŒ๋“œํ•  ๋•Œ -DPARALLEL option ์„ ์ธ์ž๋กœ ์ฃผ์ง€ ์•Š์•„ ๋ณธ๋‹ค (์œ„ ์ฝ”๋“œ์˜ #ifdef ๋ธ”๋ก ์ฐธ๊ณ ).
      • ๋•Œ๋ฌธ์— ์•„๋งˆ ์„ฑ๋Šฅ ์ด๋“์ด ์—†์„ ๊ฒƒ์ด๋‹ค.
    • 1์ฐจ์‹œ๋„ 1a: no par no opt
      • ๋ฐฉ๊ธˆ 19๊ฐœ ์ฝ”์–ด๋ฅผ ํ• ๋‹นํ•˜์—ฌ ๋“ค์–ด์˜จ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์† ํ„ฐ๋ฏธ๋„์—์„œ ์ด๋ ‡๊ฒŒ ์ž…๋ ฅํ•ด์„œ ๋นŒ๋“œํ•ด์ฃผ์ž.
          $ g++ -std=c++20 main.cpp -o main
        
      • $ ./main ํ•ด์„œ ์‹คํ–‰ (3๋ฒˆ) ํ•ด์ฃผ๋ฉด ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™”๋‹ค.
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 479 milliseconds
        
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 460 milliseconds
        
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 529 milliseconds
        
      • ๊ทธ๋Ÿฐ๋ฐ ๋งˆ์ดํฌ๋กœ๋ฒค์น˜๋งˆํฌ ํ•  ๋•Œ -O3 ๋ฅผ ๋„ฃ์ง€ ์•Š๊ณ  ํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ์—†๋‹ค.
    • 1์ฐจ์‹œ๋„ 1b: no par (O3 opt as default)
      • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์‹œ ๋นŒ๋“œํ•ด์„œ ์‹คํ–‰ํ•ด๋ณด์ž.
          $ g++ -std=c++20 -O3 main.cpp -o main
        
      • $ ./main ํ•ด์„œ ์‹คํ–‰ (3๋ฒˆ) ํ•ด์ฃผ๋ฉด ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™”๋‹ค.
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 170 milliseconds
        
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 156 milliseconds
        
          root@82b404f8eac1:/usr/src/myapp# ./main 
          No execution policy: 144 milliseconds
        
    • ์ด๋กœ๋ถ€ํ„ฐ ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
      1. ์ผ๋‹จ ๋‹น์—ฐํžˆ ์ปดํŒŒ์ผ๋Ÿฌ์ตœ์ ํ™” (O3) ๋Š” ๊ฑธ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
      2. ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ €์ •๋„ ๋‚˜์˜จ๋‹ค. (๋ฒ ์ด์Šค๋ผ์ธ ํ™•๋ณด)
        • ๋ฌผ๋ก  n ๋งˆ๋‹ค, ๋จธ์‹ ๋งˆ๋‹ค ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ์ž๊ธฐ ๋จธ์‹ ์—์„œ ์ธก์ •ํ•œ ๊ฒฐ๊ณผ๋กœ๋งŒ ๋งํ•ด์•ผ ํ•œ๋‹ค.
  2. 1์ฐจ์‹œ๋„-2 (par)
    • ์ด์ œ ๋ฒ ์ด์Šค๋ผ์ธ ์‹คํ—˜๊ฒฐ๊ณผ๊ฐ€ ํ™•๋ณด๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์–ป์–ด๋ณด์ž.
      • ps. O3 ๋Š” ํ•ญ์ƒ ๊ฑธ์–ด์ค€๋‹ค.
    • -DPARALLEL ์ธ์ž๋ฅผ ๋„ฃ์–ด์„œ ๋นŒ๋“œํ•œ๋‹ค.
        $ g++ -std=c++20 -O3 main.cpp -DPARALLEL -o main
      
    • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 3๋ฒˆ ์ •๋„ ์‹คํ–‰ํ•ด๋ณด๋ฉด
        root@82b404f8eac1:/usr/src/myapp# ./main 
        seq      : 135 milliseconds
        unseq    : 142 milliseconds
        par_unseq: 164 milliseconds
        par      : 148 milliseconds
      
        root@82b404f8eac1:/usr/src/myapp# ./main 
        seq      : 153 milliseconds
        unseq    : 151 milliseconds
        par_unseq: 131 milliseconds
        par      : 129 milliseconds
      
        root@82b404f8eac1:/usr/src/myapp# ./main 
        seq      : 146 milliseconds
        unseq    : 136 milliseconds
        par_unseq: 132 milliseconds
        par      : 144 milliseconds
      
    • โ“โ“โ“
      • ์ „ํ˜€ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ์•ˆ๋˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
    • ์•ž์„œ ์›๋ž˜ ์ฝ”๋“œ์˜ˆ์‹œ์˜€๋˜ cppreference ์— ๋‹จ์„œ๊ฐ€ ์žˆ์„ ์ง€ ๋‹ค์‹œ ๊ฐ€๋ณด์ž.

    • ์•„ํ•˜
      • -ltbb ์™€ ๊ฐ™์ด tbb ๋ฅผ ๋งํฌํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
        • gcc๋Š” (์ € ์˜ˆ์ œ์—์„œ๋Š” gcc13์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ) c++17 execution policy์˜ text code๋ฅผ binary๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” tbb๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋“ฏํ•˜๋‹ค.
    • -ltbb๋ผ๊ณ  ๋„ฃ์–ด์„œ ๋นŒ๋“œ๋ฅผ ์‹œ๋„ํ•˜๋ฉด, ์ฆ‰:
        $ g++ -std=c++20 -O3 main.cpp -DPARALLEL -ltbb -o main
      
    • ์ด๋ ‡๊ฒŒ ๋ชป์ฐพ๊ฒ ๋‹ค๊ณ  ๋งํฌ ์—๋Ÿฌ๊ฐ€ ๋œฌ๋‹ค.
        /usr/bin/ld: cannot find -ltbb: No such file or directory
        collect2: error: ld returned 1 exit status
      

4. 2์ฐจ์‹œ๋„: TBB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

  • tbb ๋ฅผ ๋”ฐ๋กœ ์„ค์น˜๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  1. ๋ฐฉ๋ฒ• 1: apt-get ์ด์šฉ
     $ apt-get install libtbb-dev
    
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด ๊ธ€ ์ž‘์„ฑ ๊ธฐ์ค€, ๋ฒ„์ „์€
      • 20.04 ์—์„œ๋Š” libtbb-dev is already the newest version (2020.1-2) ๊ฐ€
      • 22.04 ์—์„œ๋Š” libtbb-dev is already the newest version (2021.5.0-7ubuntu2) ๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ์„ค์น˜๋œ๋‹ค.
    • ํ™•์ธ ๋ฐฉ๋ฒ•
      • ์œ„์˜ apt-get install ์„ค์น˜ ํ›„ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ํ•œ๋ฒˆ ๋” ์ž…๋ ฅํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ์ถœ๋ ฅ์ด ๋‚˜์˜ค๊ณ ,
      • ํ˜น์€ ์ฝ”๋“œ ์ƒ์—์„œ /* #include <tbb/tbb.h> */ std::cout << "TBB Version: " << TBB_VERSION_MAJOR << "." << TBB_VERSION_MINOR << std::endl; ์™€ ๊ฐ™์ด ํ•ด์ฃผ์–ด๋„ ๋ฒ„์ „์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.
    • ์ฒจ์–ธ
      • ๊ตณ์ด (์ด์ œ 2024๋…„์—) Ubuntu 18.04 ์—์„œ ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
      • ๊ทธ๋‚˜์ €๋‚˜ tbb release notes ๋ฅผ ๋ณด๋ฉด 2020๋…„ ์ดˆ ์ด๋ฆ„์ด Threading Building Blocks ์—์„œ oneTBB ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. ๊ทธ ์‚ฌ์ด ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋„ ์žˆ์„๊นŒ?

        • ์•”ํŠผ ๊ทธ ์ด์œ ๋Š” ๊ณต์‹ ๋ฆฌ๋“œ๋ฏธ์— ๋”ฐ๋ฅด๋ฉด ์—์ฝ”์‹œ์Šคํ…œ์— ํŽธ์ž…๋จ ์–ด์ฉŒ๊ตฌ

  2. ๋ฐฉ๋ฒ• 2: ์ง์ ‘ ๋นŒ๋“œ
    • ๊ณต์‹ ๊นƒํ—ˆ๋ธŒ ๋ฆฌ๋“œ๋ฏธ ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๋นŒ๋“œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
      • ์ง์ ‘ ๋นŒ๋“œํ•  ๋•Œ์˜ ์žฅ์ ์€ ํŠน์ • ๋ฒ„์ „์„ ์ฝ• ์ง‘์–ด์„œ ์‚ฌ์šฉํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
    • ๋นŒ๋“œ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜๊ณผ์ •์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค ์ ์–ด๋ณด์ž๋ฉด
      • ์ผ๋‹จ $ run_tbb.22.04.sh 19 ํ•ด์„œ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋กœ ๋“ค์–ด์˜จ๋‹ค.
        • 19๋Š” ๋Œ€์ถฉ ๋งฅ์Šค ์ฝ”์–ด ์ˆซ์ž (ํ˜„์žฌ ์˜ˆ์‹œ์—์„œ๋Š” 20๊ฐœ ์ฝ”์–ด CPU์‚ฌ์šฉ ์ค‘์ด๋ฏ€๋กœ). ๊ฐ์ž ๋จธ์‹ ์— ๋งž๊ฒŒ ํ•˜๋ฉด ๋œ๋‹ค. oneTBB library๋ฅผ ๋นŒ๋“œ ํ•  ๋•Œ ๋น ๋ฅด๊ฒŒ ๋นŒ๋“œํ•˜๋ ค๋ฉด -j option์„ ์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋ฅผ ์œ„ํ•ด ์ฝ”์–ด๋ฅผ ๋งŽ์ด ๋ฌผ๊ณ  ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
      • ๊ทธ ๋‹ค์Œ๋ถ€ํ„ฐ ์•„๋ž˜์ฒ˜๋Ÿผ ํ•ด์ฃผ์ž.
          $ git clone https://github.com/oneapi-src/oneTBB
          $ cd oneTBB
          $ mkdir build 
          $ cmake -DTBB_TEST=OFF .. // test๊นŒ์ง€ ๋นŒ๋“œํ•  ํ•„์š”๋Š” ์—†๋‹ค. ์ด๊ฑธ ๋นŒ๋“œํ•˜๊ณ  ์žˆ์œผ๋ฉด ์‹œ๊ฐ„์ด ๋งค์šฐ ์˜ค๋ž˜  ๊ฑธ๋ฆฐ๋‹ค.
          $ cmake --build . -j
          $ cmake --install .
        
    • ํ˜„์žฌ ์ด ๊ธ€์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋Š” ์‹œ์ ์—์„œ git clone ํ•ด์„œ master branch์˜ ์ตœ์‹ ์„ ๋‹น๊ฒจ์™”๋”๋‹ˆ TBB Version: 2021.12 ๋กœ ์ถœ๋ ฅ๋˜์—ˆ๋‹ค.
      • ์ฐธ๊ณ ๋กœ ์•ž์„œ ubuntu22.04 ๋ฅผ ๋ฒ ์ด์Šค์ด๋ฏธ์ง€๋กœ ํ•ด์„œ, ๋””ํดํŠธ๋กœ apt-get install ๋กœ ์„ค์น˜๋œ ๊ฒƒ์˜ ๋ฒ„์ „์€ TBB Version: 2021.5 ์˜€๋‹ค.
    • ์‚ฌ์šฉํ•˜๋Š” ์ž…์žฅ์—์„œ ๊ทธ ์ฐจ์ด๋ฅผ ๋Š๋‚„ ๊ธฐ๋Šฅ์„ ์“ฐ๊ณ  ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ, ์ง์ ‘ ๋นŒ๋“œํ•ด๋ณด๋Š” ์‹ค์Šต์„ ํ•ด๋ณด์•˜๋‹ค.
    • ์ฒจ์–ธ
      • ubuntu20.04 ๋ฅผ ๋ฒ ์ด์Šค์ด๋ฏธ์ง€๋กœ ํ•ด์„œ master branch์˜ ์ตœ์‹ ์„ ๋‹น๊ฒจ์™€์„œ (์ฆ‰, TBB Version: 2021.12) ์ง์ ‘ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๋“ค์ด ๋‚˜ํƒ€๋‚œ๋‹ค.
        • ubuntu20.04 ์—์„œ apt-get install g++ ํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ version 9.4 ๊ฐ€ ์„ค์น˜๋˜๋Š”๋ฐ ์ด๊ฒŒ ์ตœ์‹  oneTBB ๋ฅผ ๋นŒ๋“œํ•  ์ˆ˜ ์—†๋Š” ๋“ฏ ํ•˜๋‹ค.
          • g++ ๋ฒ„์ „์„ 11๋กœ ๊ฐ•์ œ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•ด์ฃผ๊ณ  ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋‹ˆ ์ตœ์‹  TBB๋ฒ„์ „์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
            • ์ด๋Ÿฐ ์กฐํ•ฉ์€ ๊ฒ€์ƒ‰ํ•ด๋„ ์ž˜ ์•ˆ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‚˜๋ผ๊ณ  ์ž˜๋ชป ์˜์‹ฌํ•˜๋Š๋ผ ์‹œ๊ฐ„์„ ๋งŽ์ด ๋‚ญ๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ ๋ฒ„์ „ ํ˜ธํ™˜์„ฑ๋„ ๋Š˜ ์˜์‹ฌํ•ด๋ณด์ž. ๊ทธ๋ฆฌ๊ณ  ๋ช‡ ๊ฐœ ์กฐํ•ฉ์„ ์ง์ ‘ ์ˆ˜ํ–‰ํ•ด์„œ ๋˜๋Š” ์กฐํ•ฉ์„ ์‹คํ—˜์ ์œผ๋กœ ์ฐพ๊ณ  ๊ธฐ๋กํ•˜์ž.
  • ์„ค์น˜ํ™•์ธ
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด tbb๊ฐ€ ์–ด๋””์— ์–ด๋–ป๊ฒŒ ์„ค์น˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.
        $ find /usr/include /usr/local/include -name '*tbb*'
      
      • tip. bat์ด๋ผ๊ณ  cat๋ณด๋‹ค ์ข‹์€ ํˆด์ด ์žˆ๋Š”๋ฐ ์ด๊ฑฐ ์„ค์น˜ ํ›„ $ batcat [ํŒŒ์ผ๋ช…] ๊ณผ ๊ฐ™์ด ์ž…๋ ฅํ•˜๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ํŒŒ์ผ์„ ๋ณผ ๋•Œ ์ข€ ๋” ํŽธ์•ˆํ•˜๊ณ  ์˜ˆ์˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

5. Application ๋นŒ๋“œ

  • ์•ž์„œ ubuntu 22.04 ๊ธฐ์ค€,
    • g++ version 11.4 ๋ฅผ ์ด์šฉํ•ด์„œ,
    • TBB (oneTBB) version 2021.5 ํ˜น์€ 2021.12 ๋ฅผ ๋ฌด์‚ฌํžˆ ์„ค์น˜ํ•˜์˜€๋‹ค.
      • ps. ์ด๋ ‡๊ฒŒ ์„ค์น˜ํ•œ ๋ณ€๊ฒฝ์ ๋“ค์„ ์•ˆ ๋‚ ๋ ค๋จน๊ธฐ ์œ„ํ•ด์„œ๋Š” docker commit [์ปจํ…Œ์ด๋„ˆ์ด๋ฆ„] [์ด๋ฏธ์ง€์ด๋ฆ„:ํƒœ๊ทธ] ํ•ด์ฃผ์–ด์•ผ ์ €์žฅ์ด ๋œ๋‹ค.
        • ํ˜น์€ ์ด๋Ÿฐ ์„ค์น˜๊ณผ์ •๋“ค์„ ์œ„์˜ Dockerfile ํŒŒ์ผ์— ๋ชจ๋‘ ํ•ฉ์ณ๋‘๋Š” ๊ฒŒ ์ข‹๋‹ค.
  • ์ด๊ฒƒ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œ ๋ฐ ์„ค์น˜ ํ•œ ๊ฒƒ์ด๊ณ ,
  • ์ด์ œ ์šฐ๋ฆฌ์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œ ๋ฐ ์‹คํ–‰ํ•ด๋ณด์ž.
  1. ๋ฐฉ๋ฒ• 1: ์Šคํฌ๋ฆฝํŠธ๋กœ ๋นŒ๋“œ
    • ์•ž์„œ ์–˜๊ธฐํ–ˆ๋“ฏ, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•œ์ค„์ปท์ด๋‹ค.
      • ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์•ˆ์œผ๋กœ ๋“ค์–ด์˜จ ๋‹ค์Œ,
          $ g++ -std=c++20 -O3 main.cpp -DPARALLEL -ltbb -o main
        
      • ps. g++ version 9 ์—์„œ๋Š” c++20์ด๋ผ๊ณ  ํ•˜๋ฉด ๋ชป์•Œ์•„ ๋“ฃ๊ณ  c++2a ๋ผ๊ณ  ํ•ด์•ผ ์•Œ์•„ ๋“ฃ๋Š”๋‹ค.
    • ๊ทธ๋Ÿฌ๋ฉด ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  $ ./main ์ด๋ผ๊ณ  ํ•˜๋ฉด ์‹คํ–‰๋œ๋‹ค.
  2. ๋ฐฉ๋ฒ• 2: cmake ๊ธฐ๋ฐ˜ ๋นŒ๋“œ
    • ์‚ฌ์‹ค ํŒŒ์ผ ํ•˜๋‚˜ ์งœ๋ฆฌ ํ”„๋กœ์ ํŠธ๊ฐ€ (๋‹น์—ฐํžˆ) ์•„๋‹ ๋•Œ์—๋Š”, ์ด๊ฒŒ ์ •์„์ด๋‹ค.
    • cmake ๊ฐ™์€ ๊ฒŒ (CMakeLists.txt ํŒŒ์ผ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ) ๋”ฐ๋กœ ์‹œ๊ฐ„๋‚ด์„œ ๊ณต๋ถ€ํ•˜๊ธฐ ๋˜๊ฒŒ ๊ท€์ฐฎ๊ณ  ๊นŒ๋‹ค๋กœ์šด๋ฐ
    • ChatGPT4 ์‹œ๋Œ€๊ฐ€ ์˜ค๋ฉด์„œ ํ•ดํ”ผํ•ด์กŒ๋‹ค. โ€˜ํ•ด ์ค˜โ€™ ๋ผ๊ณ  ํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ํ•ด์ค€๋‹ค.

    • ๋ฌผ๋ก  ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒ€์ฆ์€ ํ•ด์•ผ๊ฒ ์ง€๋งŒ, ๊ฒฝํ—˜์ ์œผ๋กœ ์ด๋Ÿฐ work์€ ๋Œ€์ฒด๋กœ ์ž˜ ํ•œ๋‹ค.
    • ์ €๋ ‡๊ฒŒ CMakeLists.txt ํŒŒ์ผ์„ ์ž‘์„ฑํ•œ ๋’ค ํ•˜๋˜๋Œ€๋กœ ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.
      • ์ฆ‰, ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์•ˆ์œผ๋กœ ๋“ค์–ด์˜จ ๋‹ค์Œ,
          $ mkdir build 
          $ cd build 
          $ cmake ..
          $ make -j
        
    • ๊ทธ๋Ÿฌ๋ฉด ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  $ ./main ์ด๋ผ๊ณ  ํ•˜๋ฉด ์‹คํ–‰๋œ๋‹ค.

6. ์‹คํ–‰ ๊ฒฐ๊ณผ

  • ์ด์ œ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ์ž˜ ๋œ๋‹ค. 5๋ฒˆ ์‹คํ–‰ํ•ด๋ณด๋ฉด ์ผ๊ด€๋˜๊ฒŒ par ์‚ฌ์šฉ ์‹œ ๊ฐœ์„ ์ด ์žˆ์Œ (์ฝ”์–ด 20๊ฐœ ์‚ฌ์šฉ) ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
      root@65461ff9d981:/usr/src/myapp/build# ./main 
    
      seq      : 147 milliseconds
      unseq    : 145 milliseconds
      par_unseq: 24 milliseconds
      par      : 24 milliseconds
    
      root@65461ff9d981:/usr/src/myapp/build# ./main 
      seq      : 138 milliseconds
      unseq    : 131 milliseconds
      par_unseq: 20 milliseconds
      par      : 21 milliseconds
    
      root@65461ff9d981:/usr/src/myapp/build# ./main 
      seq      : 146 milliseconds
      unseq    : 136 milliseconds
      par_unseq: 22 milliseconds
      par      : 21 milliseconds
    
      root@65461ff9d981:/usr/src/myapp/build# ./main 
      seq      : 132 milliseconds
      unseq    : 132 milliseconds
      par_unseq: 20 milliseconds
      par      : 21 milliseconds
    
      root@65461ff9d981:/usr/src/myapp/build# ./main 
      seq      : 129 milliseconds
      unseq    : 129 milliseconds
      par_unseq: 22 milliseconds
      par      : 25 milliseconds
    

7-1. Ablation 1: core ์ˆ˜ ๋‹ฌ๋ฆฌํ•ด๋ณด๋ฉฐ

  • ๊ทธ๋Ÿผ ์ด์ œ ์ฝ”์–ด์ˆ˜๋ฅผ 1๊ฐœ๋ถ€ํ„ฐ 20๊ฐœ๊นŒ์ง€ ๋‹ฌ๋ฆฌํ•ด๊ฐ€๋ฉฐ ์‹คํ—˜ํ•ด๋ณด์ž.
    • ์‹คํ—˜ ํ™˜๊ฒฝ์€ i7-13700H
  • ๊ทผ๋ฐ ๋งค๋ฒˆ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๋“ค์–ด๊ฐ”๋‹ค๊ฐ€ ๋นŒ๋“œ ์ƒˆ๋กœ ํ–ˆ๋‹ค๊ฐ€ ๋‚˜์™”๋‹ค๊ฐ€ ํ•˜๊ธฐ ๊ท€์ฐฎ์œผ๋‹ˆ ์ž๋™ํ™” ํ•ด๋ณด์ž
  • ๋จผ์ € ์‹คํ—˜ ํ•œ ๋ฒˆ์˜ ์ˆ˜ํ–‰์„ ํ•˜๋‚˜์˜ ์Šคํฌ๋ฆฝํŠธํ™”๋ฅผ ํ•œ๋‹ค.
      docker run -ti --rm \
          --cpuset-cpus="0-$1" \
          --name my-running-app-2204 \
          -v $PWD:/usr/src/myapp \
          cpp-experiment:22.04 \
          /bin/bash -c "cd /usr/src/myapp/build && \
              rm -rf * && \
              cmake .. && \
              make -j$num_cores && \
              ./main"
    
      echo ""
      echo We used 0 to $1 cores 
    
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋„์ปค์ปจํ…Œ์ด๋„ˆ ์ง„์ž… ํ›„ bash ํ„ฐ๋ฏธ๋„์—์„œ ๋Œ€๊ธฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ main์„ ๋นŒ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•˜๊ณ  ์ข…๋ฃŒํ•˜๊ณ  ๋น ์ ธ๋‚˜์˜จ๋‹ค.
      • --rm ์˜ต์…˜์„ ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…Œ์ด๋„ˆ๋Š” ํ• ์ผ์„ ๋‹คํ•˜๊ณ  ์ข…๋ฃŒ ํ›„ ์‚ญ์ œ๋œ๋‹ค.
    • ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ run_tbb.22.04_auto.sh ๋ผ๊ณ  ํ•˜์ž.
  • ๊ทธ ๋‹ค์Œ ์ด๋ ‡๊ฒŒ ํ•œ๋‹ค์Œ ์ด๊ฑธ ์‹คํ–‰ํ•˜๊ณ  ์ปคํ”ผํ•œ๋ชจ๊ธˆ ๋งˆ์‹œ๊ณ  ์˜ค๋ฉด ๋œ๋‹ค.
      #!/bin/bash
    
      # 0๋ถ€ํ„ฐ 19๊นŒ์ง€ ๋ฐ˜๋ณต
      for i in {0..19}
      do
          echo "Running with 0 to $i cores"
          ./run_tbb.22.04_auto.sh $i
          echo ""
      done
    
  • ๊ทธ ๋‹ค์Œ terminal ์— ์ถœ๋ ฅ๋œ ํ…์ŠคํŠธ ๊ฒฐ๊ณผ๋ฌผ์„ ๋Œ€์ถฉ ๋ณต์‚ฌํ•ด์„œ ChatGPT์—๊ฒŒ ๊ทธ๋ ค์ค˜๋ผ๊ณ  ๋งํ•˜๋ฉด

    • ํ•ด์„
      • note: ์ผ๋‹จ ๊ฐ ๊ฐ€๋กœ์ถ• ๋ฐ์ดํ„ฐํฌ์ธํŠธ๋งˆ๋‹ค ์—ฌ๋Ÿฌ๋ฒˆ ์‹คํ–‰ํ•ด์„œ ํ‰๊ท ๋‚ธ๊ฒŒ ์•„๋‹ˆ๋ผ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— + ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋„ ๋งŽ์ด ๋Œ๊ณ  ์žˆ๋Š” ์ƒํƒœ์—์„œ ๊ทธ๋ƒฅ ์‹คํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋…ธ์ด์ฆˆ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค (์˜ˆ: x=19).
      • ์ „์ฒด์ ์ธ ๊ฒฝํ–ฅ๋งŒ ๋ณด๋ฉด ๊ทธ๋ž˜๋„ ํ™•์—ฐํžˆ ๋ณด์ธ๋‹ค.
      • par ์ด๋“์ด ํ™•์‹คํžˆ ์žˆ์—ˆ๋‹ค.
      • unseq (๊ฒ€์ •) ์€ seq์— ๋น„ํ•ด ๋Œ€์ถฉ plot์ด ์•„๋ž˜์— ๊ฒฝํ–ฅ์ด ์œ„์น˜ํ•˜๊ธด ํ•˜์ง€๋งŒ ๋น„์Šทํ•ด๋ณด์ธ๋‹ค.
        • ps. unseq (~ simd) ์ž์ฒด๋Š” single core ์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋‹ค. ์ด ํƒœ์Šคํฌ๊ฐ€ vectorized ๋˜๊ธฐ์— ์ ํ•ฉํ•œ ํƒœ์Šคํฌ์ธ์ง€ ์•„๋‹Œ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๊ณ  ์ผ๋‹จ ์‹คํ—˜์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ๊ฒ€์ฆํ•ด๋ณด๊ณ  ๋„˜์–ด๊ฐ€๋Š” ์ˆ˜๋ฐ–์—โ€ฆ ์—†์ง€๋งŒ ์ถ”ํ›„์— ๊ณต๋ถ€ํ•ด๋ณด๋„๋ก ํ•˜์ž.
      • ์ฝ”์–ด 1๊ฐœ์—์„œ 2๊ฐœ, 3๊ฐœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€๋Š” ์ •์งํ•˜๊ฒŒ n ๋ฐฐ์— ๊ฐ€๊นŒ์šด ์ด๋“์„ ๋ณด์•˜๋‹ค.
        • ๋ฌผ๋ก  ์ด๋Š” ํƒœ์Šคํฌ๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ธก์ •์„ ํ†ตํ•ด ํŒ๋‹จํ•ด์•ผ ๋˜๊ฒ ๋‹ค.
        • ์ฝ”์–ด๋ฅผ 20๊ฐœ ์“ด๋‹ค๊ณ  ํ•ด์„œ ๋“ค์ธ ๋…ธ๋ ฅ๋Œ€๋น„ 20๋ฐฐ์˜ ์ด๋“์ด ์žˆ์ง€๋Š” ์•Š์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

7-2. Ablation 2: core ์ˆ˜ ๋‹ฌ๋ฆฌํ•ด๋ณด๋ฉฐ on ๋‹ค๋ฅธ ์˜ˆ์ œ

  • 500๋งŒ๊ฐœ ํฌ์ธํŠธ์˜ ์ขŒํ‘œ๋ฅผ ๋ณ€ํ™˜ํ•ด๋ณด์ž.
      #include <array>
      #include <chrono>
      #include <execution>
      #include <iostream>
      #include <valarray>
    
      struct Point3D {
          std::valarray<double> coordinates;
    
          Point3D(double x, double y, double z) : coordinates({x, y, z}) {}
      };
    
      using Matrix3x3 = std::array<std::valarray<double>, 3>;
    
      Point3D applyTransformation(const Point3D& point,
                                  const Matrix3x3& rotationMatrix,
                                  const Point3D& translation) {
          std::valarray<double> rotated(3);
          for (int i = 0; i < 3; ++i) {
              rotated[i] = (rotationMatrix[i] * point.coordinates).sum();
          }
          return Point3D(rotated[0] + translation.coordinates[0],
                         rotated[1] + translation.coordinates[1],
                         rotated[2] + translation.coordinates[2]);
      }
    
      int main() {
          // ์˜ˆ์ œ ๋ฐ์ดํ„ฐ: n๊ฐœ 3D ํฌ์ธํŠธ
          std::vector<Point3D> points(5'000'000, Point3D(1.0, 2.0, 3.0));
    
          // ํšŒ์ „ ํ–‰๋ ฌ ๋ฐ ์ด๋™ ๋ฒกํ„ฐ ์ •์˜
          Matrix3x3 rotationMatrix = {std::valarray<double>{0, -1, 0},
                                      std::valarray<double>{1, 0, 0},
                                      std::valarray<double>{0, 0, 1}};
          Point3D translation(1.0, 2.0, 3.0);
    
          // ๋ณ€ํ™˜ ์‹œ์ž‘ ์‹œ๊ฐ„ ์ธก์ •
          auto start = std::chrono::high_resolution_clock::now();
    
          // ๋ชจ๋“  ํฌ์ธํŠธ์— ๋Œ€ํ•ด ๋ณ€ํ™˜ ์ ์šฉ
    
          std::for_each(std::execution::par /* CHANGE HERE! */, 
                        points.begin(), points.end(),
                        [&rotationMatrix, &translation](auto& point) {
                            point = applyTransformation(point, rotationMatrix,
                                                        translation);
                        });
    
          // ๋ณ€ํ™˜ ์ข…๋ฃŒ ์‹œ๊ฐ„ ์ธก์ •
          auto end = std::chrono::high_resolution_clock::now();
    
          // ์†Œ์š”๋œ ์‹œ๊ฐ„ ๊ณ„์‚ฐ ๋ฐ ์ถœ๋ ฅ
          auto duration =
              std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
                  .count();
          std::cout << "Transformations completed in " << duration << " ms"
                    << std::endl;
    
          return 0;
      }
    
  • ๊ฒฐ๊ณผ

    • ์ด ์‹คํ—˜์—์„œ๋Š” vectorization ์„ ์‹œ๋„ํ•˜๋Š” ๊ฒƒ (== unseq) ์ด ์‹œ๊ฐ„์„ ๋” ์žก์•„๋จน์—ˆ๋‹ค.
    • par ์‚ฌ์šฉ์‹œ ์—ญ์‹œ ์ดˆ๋ฐ˜ 3-4 ์ฝ”์–ด ์ •๋„๊นŒ์ง€ ์„ ํ˜•์ ์ธ ์„ฑ๋Šฅ์ด๋“์ด ์žˆ๊ณ  ์ดํ›„์—๋Š” under linear ํ•˜๋‹ค.

7-3. Ablation 3: ๋‹ค๋ฅธ ๋จธ์‹ 

  • AMD Ryzenโ„ข 5 7530U ๋…ธํŠธ๋ถ์—์„œ๋„ TBB๊ฐ€ ์ž˜ ์„ค์น˜๋˜์—ˆ๋‹ค.
    • ์œ„์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์—์„œ ์„ฑ๋Šฅ ์ด๋“์„ ์—ญ์‹œ ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๊ฒฐ๋ก 

  • C++17์— ๋„์ž…๋œ execution policy๋Š” c++ ์˜ functional ํ•œ algorithm์— ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹๋‹ค.
    • ์‚ฌ์šฉ์ž๊ฐ€ ๋“ค์ด๋Š” ์ฝ”๋“œ ์ž‘์„ฑ์—์„œ์˜ ๋…ธ๋ ฅ์€ ๊ฑฐ์˜ ์—†์œผ๋ฉด์„œ ๋ฉ€ํ‹ฐ์ฝ”์–ด ์ด๋“์„ ์‰ฝ๊ฒŒ ์ฑ™๊ธธ ์ˆ˜ ์žˆ๋‹ค.
  • (gcc์˜ ๊ฒฝ์šฐ) execution policy๋ฅผ ์ปดํŒŒ์ผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” tbb ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํฌํ•ด์•ผ ํ•œ๋‹ค.
    • gcc ๋ฒ„์ „๊ณผ tbb ๋ฒ„์ „์„ ์ž˜ ๋งž์ถฐ์ฃผ์ž. ํ˜น์€ apt-get ์œผ๋กœ ์„ค์น˜ํ–ˆ๋”๋ผ๋„ gcc ์™€ tbb ๋ฒ„์ „์ด ๊ฐ๊ฐ ์–ด๋– ํ•œ์ง€ ์Šต๊ด€์ ์œผ๋กœ ๊ด€์ฐฐํ•˜๊ณ  ๋„˜์–ด๊ฐ€์ž.
  • ๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ์„ค์น˜ํ•œ TBB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ๊ธฐ๋ณธ์ ์ธ ๋ฒค์น˜๋งˆํฌ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋“ค (์œ„์—์„œ๋Š” ๋‘ ๊ฐœ๋ฅผ ์†Œ๊ฐœ) ์„ ์ง์ ‘ ๊ตฌ์„ฑํ•˜๊ณ  ์‹คํ—˜ํ•ด๋ณด์•˜๋‹ค.
  • ์‹ค์Šต 2ํŽธ์—์„œ๋Š” oneTBB์˜ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋“ค ๋ฐ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ์— ๊ด€ํ•œ ์ข€ ๋” ์ด๋ก ์ ์ธ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.