티스토리 뷰

병렬프로그래밍

Pthread 연습 (1)

이불코딩 2018. 3. 25. 09:46

Pthread 배열합


// Sum array (pthread)
// Author : ky15534
// 2018-03-25

#define HAVE_STRUCT_TIMESPEC
#include <chrono>
#include <iostream>
#include <pthread.h>
#include <random>
#include <string>

#define MAX 7654321
#define MAX_THREAD 4
#define CURRENT_TIME std::chrono::system_clock::now()

typedef long long ll;
ll a[MAX];
ll sum[MAX_THREAD];
ll total_ans; // without pthread
ll total_sum; // with pthread
int part;

void Init() {
    std::random_device rd;
    std::mt19937 gen(rd());

    for (int i = 0; i < MAX; ++i) {
        a[i] = gen() % 10;
    }
}

void* Slave(void* data)
{
    int core = part++;

    for (int i = core; i < MAX; i += MAX_THREAD)
        sum[core] += a[i];

    return (NULL);
}

void SumPthread() {
    for (int i = 0; i < MAX; ++i) {
        total_ans += a[i];
    }
}

void Sum() {
    pthread_t threads[MAX_THREAD];

    for (int i = 0; i < MAX_THREAD; i++)
        pthread_create(&threads[i], NULL, Slave, (void*)&i);

    for (int i = 0; i < MAX_THREAD; i++)
        pthread_join(threads[i], NULL);

    for (int i = 0; i < MAX_THREAD; i++)
        total_sum += sum[i];
}

void Solve() {
    std::chrono::system_clock::time_point start;
    std::chrono::duration<double> sec;
    void(*fp[2])() = { Sum, SumPthread };
    std::string str[2] = { "Sum normal : ","Sum pthread: " };
    for (int i = 0; i < 2; ++i) {
        start = CURRENT_TIME;
        fp[i]();
        sec = CURRENT_TIME - start;
        std::cout << str[i] << sec.count() << "seconds\n";
    }
}

void Check() {
    if (total_sum != total_ans) {
        std::cout << "답이 틀렸습니다.\n";
        exit(1);
    }
    std::cout << "sum is " << total_sum << std::endl;
}

int main(int argc, char *argv[]) {
    Init();
    Solve();
    Check();
    return EXIT_SUCCESS;
}


Pthread 행렬 곱


// Matrix Multiplication (pthread)
// Author : ky15534
// 2018-03-25 : 코드 완성
// 2018-04-08 : 코드 1차 수정

#define HAVE_STRUCT_TIMESPEC
#define HAVE_PTHREAD

#include <chrono>       // duration
#include <iostream>     // std::cout
#include <random>       //
#include <string>       // memset, memcmp
#include <cassert>      // assert

#ifdef HAVE_PTHREAD
#include <pthread.h>    // pthread
#else
#include <thread>       // std::thread
#endif // HAVE_PTHREAD

#define MAX 1024
#define MAX_THREAD 4
#define CURRENT_TIME std::chrono::system_clock::now()

// Variables
int matA[MAX][MAX];
int matB[MAX][MAX];
int mat1[MAX][MAX];
int mat2[MAX][MAX];
int mat3[MAX][MAX];
int part = 0;

// Functions
void InitMatrix();
#ifdef HAVE_PTHREAD
void *Slave1(void *data);
void *Slave2(void *data);
#else
void Slave1();
void Slave2();
#endif // HAVE_PTHREAD
void MatMulNormal();
void MatMulThread();
void MatMulThreadFast();
bool IsSame(const int a[][MAX], const int b[][MAX]);
void Solve();
void Check();

// main
int main(int argc, char *argv[]) {
    while (1) {
        InitMatrix();
        Solve();
        Check();
    }
    return EXIT_SUCCESS;
}

void InitMatrix() {
    std::random_device rd;
    std::mt19937 gen(rd());

    memset(mat1, 0, sizeof(mat1));
    memset(mat2, 0, sizeof(mat2));
    memset(mat3, 0, sizeof(mat3));

    // 난수 생성
    for (int i = 0; i < MAX; ++i) {
        for (int j = 0; j < MAX; ++j) {
            matA[i][j] = gen() % 10;
            matB[i][j] = gen() % 10;
        }
    }
    std::cout << "<<<Matrix Size : " << MAX << " x " << MAX << ">>>\n";
}

#ifdef HAVE_PTHREAD
void *Slave1(void *data)
{
    int core = part++;

    for (int i = core; i < MAX; i += MAX_THREAD) {
        for (int j = 0; j < MAX; ++j) {
            for (int k = 0; k < MAX; ++k) {
                mat2[i][j] += matA[i][k] * matB[k][j];
            }
        }
    }

    return NULL;
}

void *Slave2(void *data)
{
    int core = part++;

    for (int i = core; i < MAX; i += MAX_THREAD) {
        for (int k = 0; k < MAX; ++k) {
            for (int j = 0; j < MAX; ++j) {
                mat3[i][j] += matA[i][k] * matB[k][j];
            }
        }
    }

    return NULL;
}

// using thread
void MatMulThread() {
    part = 0;
    pthread_t threads[MAX_THREAD];

    for (int i = 0; i < MAX_THREAD; ++i) {
        pthread_create(&threads[i], NULL, Slave1, (void*)&i);
    }

    for (int i = 0; i < MAX_THREAD; ++i) {
        pthread_join(threads[i], NULL);
    }
}

void MatMulThreadFast() {
    part = 0;
    pthread_t threads[MAX_THREAD];

    for (int i = 0; i < MAX_THREAD; ++i) {
        pthread_create(&threads[i], NULL, Slave2, (void*)&i);
    }

    for (int i = 0; i < MAX_THREAD; ++i) {
        pthread_join(threads[i], NULL);
    }
}

#else
void Slave1()
{
    int core = part++;

    for (int i = core; i < MAX; i += MAX_THREAD) {
        for (int j = 0; j < MAX; ++j) {
            for (int k = 0; k < MAX; ++k) {
                mat2[i][j] += matA[i][k] * matB[k][j];
            }
        }
    }
}

void Slave2()
{
    int core = part++;

    for (int i = core; i < MAX; i += MAX_THREAD) {
        for (int k = 0; k < MAX; ++k) {
            for (int j = 0; j < MAX; ++j) {
                mat3[i][j] += matA[i][k] * matB[k][j];
            }
        }
    }
}

void MatMulThread() {
    part = 0;
    std::thread threads[MAX_THREAD];

    for (int i = 0; i < MAX_THREAD; ++i) {
        threads[i] = std::thread(Slave1);
    }

    for (int i = 0; i < MAX_THREAD; ++i) {
        threads[i].join();
    }
}

void MatMulThreadFast() {
    part = 0;
    std::thread threads[MAX_THREAD];

    for (int i = 0; i < MAX_THREAD; ++i) {
        threads[i] = std::thread(Slave2);
    }

    for (int i = 0; i < MAX_THREAD; ++i) {
        threads[i].join();
    }
}
#endif // HAVE_PTHREAD

void MatMulNormal() {
    for (int i = 0; i < MAX; ++i) {
        for (int j = 0; j < MAX; ++j) {
            for (int k = 0; k < MAX; ++k) {
                mat1[i][j] += matA[i][k] * matB[k][j];
            }
        }
    }
}

void Solve() {
    void(*fp[3])() = { MatMulNormal, MatMulThread, MatMulThreadFast };
    std::chrono::system_clock::time_point start[3];
    std::chrono::duration<double> sec[3];
    std::string str[3] = { "Normal : ","Thread : ", "Thread++: " };
    for (int i = 0; i < 3; ++i) {
        start[i] = CURRENT_TIME;
        fp[i]();
        sec[i] = CURRENT_TIME - start[i];
        std::cout << str[i] << sec[i].count() << " second\n";
    }
    // 속도 비교
    std::cout << "Normal : Thread == ";
    std::cout << sec[0] / sec[1] << " : 1\n";
    std::cout << "Normal : Thread : Thread++ == ";
    std::cout << sec[0] / sec[2] << " : " << sec[1] / sec[2] << " : 1\n";
}

bool IsSame(const int dst[][MAX], const int src[][MAX]) {
    return (memcmp(dst, src, sizeof(dst)) == 0);
}

void Check() {
    assert(IsSame(mat1, mat2));
    assert(IsSame(mat1, mat3));
    std::cout << "\n";
}



행렬 곱 코드를 고쳤더니 라인수가 두배로 늘어버렸다..

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함