티스토리 뷰
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";
}
행렬 곱 코드를 고쳤더니 라인수가 두배로 늘어버렸다..
댓글