Verified Commit eb0426e7 authored by Heinrich Fenkart's avatar Heinrich Fenkart
Browse files

Initial commit

parents
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
{
"files.associations": {
"chrono": "cpp",
"iostream": "cpp"
}
}
\ No newline at end of file
CCX := clang++
FLAGS = -Wall -Wextra -std=c++17 -pedantic-errors -pthread -DPH2 -DSIZE=13
DEBUG ?= 0
ifeq ($(DEBUG), 1)
FLAGS += -DDEBUG -Og -g
else
FLAGS += -O3 -DNDEBUG
endif
a.out: pthread.cpp
$(CCX) $(FLAGS) $? -o $@
std.out: std.cpp
$(CCX) $(FLAGS) $? -o $@
.PHONY: clean all
clean:
rm *.out
all: a.out std.out
\ No newline at end of file
#include <iostream>
#include <cmath>
#include <vector>
#include <chrono>
#include <pthread.h>
#ifdef DEBUG
# define TRACE(x) std::cerr << x << std::endl;
#else
# define TRACE(x)
#endif
using std::cin;
using std::cout;
using std::endl;
using vec_t = std::vector<unsigned>;
struct thread_data {
vec_t* primes;
unsigned id;
unsigned start;
unsigned end;
static unsigned next_id;
thread_data () : id {next_id++} {}
};
unsigned thread_data::next_id {1};
bool is_prime (int zahl) {
unsigned i {3};
unsigned stop {static_cast<unsigned>(std::sqrt(zahl)) + 1};
for (; i <= stop; i += 2)
if (zahl % i == 0)
return false;
return true;
}
void* generate_primes (void* arg) {
auto args {static_cast<thread_data*>(arg)};
unsigned candidate {args->start};
TRACE("hello from thread " << args->id)
TRACE("[thread" << args->id << "] start: " << args->start)
TRACE("[thread" << args->id << "] end: " << args->end)
TRACE("[thread" << args->id << "] primes addr: " << endl << "&" << args->primes)
for (; candidate <= args->end; candidate += 2)
if (is_prime(candidate))
args->primes->push_back(candidate);
TRACE("[thread" << args->id << "] primes size: " << args->primes->size())
pthread_exit(0);
}
int main (int argc, char **argv) {
int threads_count {argc > 1 ? std::stoi(argv[1]) : 2};
unsigned start {1'000'001};
unsigned stop {30'048'731};
unsigned range {stop - start};
unsigned remainder {range % threads_count};
size_t expected_size {1'800'000};
pthread_t* threads = new pthread_t [threads_count];
thread_data* threads_data = new thread_data [threads_count];
pthread_attr_t attr;
vec_t** results = new vec_t* [threads_count];
std::vector<unsigned> primes;
unsigned per_thread {range / threads_count};
primes.reserve(expected_size);
for (int i {0}; i < threads_count; ++i) {
auto res {new vec_t};
res->reserve(per_thread);
results[i] = res;
}
TRACE("Creating " << threads_count << " threads")
TRACE("Search range: " << range)
TRACE("Per thread load: " << per_thread)
TRACE("Division remainder: " << remainder)
// Initialize and set thread joinable
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
auto startTime {std::chrono::high_resolution_clock::now()};
for (int i {0}; i < threads_count; ++i) {
unsigned thread_start {start + (per_thread * i)};
unsigned thread_end {start + (per_thread * (i + 1)) - 1};
if (thread_start % 2 == 0)
++thread_start;
if (i + 1 == threads_count) // last thread
thread_end += 1 + remainder;
threads_data[i].primes = results[i];
threads_data[i].start = thread_start;
threads_data[i].end = thread_end;
if (auto result = pthread_create(&threads[i], &attr, generate_primes, static_cast<void*>(&threads_data[i])))
throw result;
}
// free attribute and wait for the other threads
pthread_attr_destroy(&attr);
for (int i {0}; i < threads_count; ++i)
if (auto result = pthread_join(threads[i], NULL))
throw result;
auto endTime {std::chrono::high_resolution_clock::now()};
TRACE(endl)
cout << "Done calculating after " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << endl;
for (int i {0}; i < threads_count; ++i)
primes.insert(primes.end(), threads_data[i].primes->begin(), threads_data[i].primes->end());
cout << "Found " << primes.size() << " prime numbers" << endl;
cout << "Largest prime found: " << primes.at(primes.size() - 1) << endl;
assert((primes.size() == 1782219));
assert((primes.at(primes.size() - 1) == 30048731));
return 0;
}
\ No newline at end of file
#include <iostream>
#include <cmath>
#include <vector>
#include <chrono>
#include <thread>
#ifdef DEBUG
# define TRACE(x) std::cerr << x << std::endl;
#else
# define TRACE(x)
#endif
using std::cin;
using std::cout;
using std::endl;
bool is_prime (int zahl) {
unsigned i {3};
unsigned stop {static_cast<unsigned>(std::sqrt(zahl)) + 1};
for (; i <= stop; i += 2)
if (zahl % i == 0)
return false;
return true;
}
void generate_primes (std::vector<unsigned>& primes, unsigned candidate, unsigned end) {
for (; candidate <= end; candidate += 2)
if (is_prime(candidate))
primes.push_back(candidate);
}
int main (int argc, char **argv) {
int threads_count {argc > 1 ? std::stoi(argv[1]) : 2};
unsigned start {1'000'001};
unsigned stop {30'048'731};
unsigned range {stop - start};
unsigned remainder {range % threads_count};
size_t expected_size {1'800'000};
std::vector<unsigned> primes;
std::vector<std::thread> threads(threads_count);
std::vector<std::vector<unsigned>> results(threads_count);
unsigned per_thread {range / threads_count};
primes.reserve(expected_size);
TRACE("Creating " << threads_count << " threads")
TRACE("Search range: " << range)
TRACE("Per thread load: " << per_thread)
TRACE("Division remainder: " << remainder)
for (int j {0}; j < threads_count; ++j) {
results.emplace_back();
results.at(j).reserve(expected_size / threads_count);
}
auto startTime {std::chrono::high_resolution_clock::now()};
for (int i {0}; i < threads_count; ++i) {
unsigned thread_start {start + (per_thread * i)};
unsigned thread_end {start + (per_thread * (i + 1)) - 1};
if (thread_start % 2 == 0)
++thread_start;
if (i + 1 == threads_count) // last thread
thread_end += 1 + remainder;
threads.emplace_back(generate_primes, std::ref(results.at(i)), thread_start, thread_end);
}
for (auto& t : threads)
if (t.joinable())
t.join();
auto endTime {std::chrono::high_resolution_clock::now()};
TRACE(endl)
cout << "Done calculating after " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms" << endl;
for (const auto& r : results)
primes.insert(primes.end(), r.begin(), r.end());
cout << "Found " << primes.size() << " prime numbers" << endl;
cout << "Largest prime found: " << primes.at(primes.size() - 1) << endl;
assert((primes.size() == 1782219));
assert((primes.at(primes.size() - 1) == 30048731));
return 0;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment