Skip to content

Instantly share code, notes, and snippets.

@vakho10
Created September 9, 2019 14:29
Show Gist options
  • Save vakho10/4224040b31099fbb08294324783fbe74 to your computer and use it in GitHub Desktop.
Save vakho10/4224040b31099fbb08294324783fbe74 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <random>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <thread>
#include <fstream>
#include <filesystem>
void _accumulate(double* first, double* last, double& response) {
response = std::accumulate(first, last, 0.);
}
double* randomArray(size_t size, int from, int to) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis(from, to);
double* arr = new double[size];
for (size_t i = 0; i < size; i++)
{
arr[i] = dis(gen);
}
return arr;
}
void emptyFunction() {}
void print(double* arr, size_t size) {
std::cout << "[";
for (size_t i = 0; i < size; i++)
{
std::cout << arr[i];
if (i < size - 1) {
std::cout << ", ";
}
}
std::cout << "]" << std::endl;
}
double getEmtpyThreadTime(size_t size)
{
size_t middle = size / 2;
double* times = new double[size];
std::chrono::time_point<std::chrono::high_resolution_clock> start, finish;
for (size_t i = 0; i < size; i++) {
start = std::chrono::high_resolution_clock::now();
std::thread t1(emptyFunction);
std::thread t2(emptyFunction);
t1.join();
t2.join();
finish = std::chrono::high_resolution_clock::now();
long long time = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
times[i] = time / (double)1000000;
}
// Sort and take middle
std::sort(times, times + size);
return times[middle];
}
double getTwoThreadsTime(double* arr, size_t arrSize, double emptyThreadsTime)
{
size_t size = 9;
size_t middle = size / 2;
double* times = new double[size];
double sum = 0;
std::chrono::time_point<std::chrono::high_resolution_clock> start, finish;
for (size_t i = 0; i < size; i++) {
start = std::chrono::high_resolution_clock::now();
double sum1, sum2;
std::thread t1(_accumulate, arr, arr + arrSize / 2, std::ref(sum1));
std::thread t2(_accumulate, arr + arrSize / 2, arr + arrSize, std::ref(sum2));
t1.join();
t2.join();
sum = sum1 + sum2;
finish = std::chrono::high_resolution_clock::now();
long long time = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
times[i] = time / (double)1000000 - emptyThreadsTime; // Minus empty thread time (this may result in time being less than zero!)
}
// Sort and take middle
std::sort(times, times + size);
return times[middle];
}
double getTimeOfAccumulateFully(double* arr, size_t arrSize) {
size_t size = 9;
size_t middle = size / 2;
double* times = new double[size];
double sum = 0;
std::chrono::time_point<std::chrono::high_resolution_clock> start, finish;
for (size_t i = 0; i < size; i++) {
start = std::chrono::high_resolution_clock::now();
sum = std::accumulate(arr, arr + arrSize, 0.);
finish = std::chrono::high_resolution_clock::now();
long long time = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
times[i] = time / (double)1000000;
}
std::cout << "sum = " << sum << std::endl;
// Sort and take middle
std::sort(times, times + size);
return times[middle];
}
double getTimeOfAccumulateByDivision(double* arr, size_t arrSize) {
size_t size = 9;
size_t middle = size / 2;
double* times = new double[size];
double sum = 0;
std::chrono::time_point<std::chrono::high_resolution_clock> start, finish;
for (size_t i = 0; i < size; i++) {
start = std::chrono::high_resolution_clock::now();
sum = std::accumulate(arr + arrSize / 2, arr + arrSize, std::accumulate(arr, arr + arrSize / 2, 0.));
finish = std::chrono::high_resolution_clock::now();
long long time = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
times[i] = time / (double)1000000;
}
// Sort and take middle
std::sort(times, times + size);
return times[middle];
}
int main()
{
std::cout << "App started." << std::endl;
double emptyThreadsTime = getEmtpyThreadTime(200001);
std::cout << "Empty thread time ~= " << emptyThreadsTime << " milliseconds." << std::endl;
size_t maxArraySize = 10000;
double* arr = new double[maxArraySize];
if (!std::experimental::filesystem::exists("arr.txt")) {
arr = randomArray(maxArraySize, -100, 100);
std::ofstream ofs("arr.txt");
for (size_t i = 0; i < maxArraySize; i++) {
ofs << arr[i] << std::endl;
}
}
else {
std::ifstream ifs("arr.txt");
for (size_t i = 0; i < maxArraySize; i++) {
ifs >> arr[i];
}
}
for (size_t arrSize = 100; arrSize < maxArraySize; arrSize += 100)
{
std::cout << "N = " << arrSize << std::endl;
double noThreadsTime = getTimeOfAccumulateFully(arr, arrSize);
std::cout << "Accumulate ~= " << noThreadsTime << " milliseconds." << std::endl;
// Approximately takes the same time as above!
//std::cout << "Accumulate divided ~= " << getTimeOfAccumulateByDivision(arr, size) << " milliseconds." << std::endl;
double threadsTime = getTwoThreadsTime(arr, arrSize, emptyThreadsTime);
std::cout << "Two Threads ~= " << threadsTime << " milliseconds." << std::endl;
std::cout << std::endl;
if (0 < threadsTime // ზოგჯერ ეს არის უარყოფითი :(
&& threadsTime < noThreadsTime) {
break;
}
}
std::cout << "App finished gracefully." << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment