Created
September 9, 2019 14:29
-
-
Save vakho10/4224040b31099fbb08294324783fbe74 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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