Skip to content

Instantly share code, notes, and snippets.

@binkiklou
Created July 20, 2022 02:04
Show Gist options
  • Select an option

  • Save binkiklou/86a969945cdace49488a38cf7d7003b9 to your computer and use it in GitHub Desktop.

Select an option

Save binkiklou/86a969945cdace49488a38cf7d7003b9 to your computer and use it in GitHub Desktop.
Calculates a lot of collatz number fast
// It is 4AM and I cannot sleep, so here is this multithreaded collatz conjecture calculator
// You can specifiy the number of numbers to calculate via the command line, or it defaults to 100
// This code is awfull, and there are a lot of ways to optimize it that I can think of
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <chrono>
#include <fstream>
#define TSEARCH_SIZE 10000000
int find(int number)
{
int i = 0;
long remainder = number;
while(remainder != 1)
{
if(remainder % 2 == 0)
{
remainder = remainder / 2;
}
else
{
remainder = (3 * remainder) + 1;
}
i++;
}
return i;
}
void find_for(int min, int max, int* fcount, std::mutex* fmut, int i, std::vector<std::pair<int,int>>* results)
{
std::cout<<"("<<i<<")"<<"Thread finding for "<<min+1<<" to "<<max<<std::endl;
for(int x = min + 1; x <= max; x++)
{
results->push_back(std::make_pair(x, find(x)) );
}
fmut->lock();
*fcount += 1;
fmut->unlock();
std::cout<<"("<<i<<")"<<"Thread finished"<<std::endl;
}
int main(int argc, char** argv)
{
auto start = std::chrono::steady_clock::now();
std::mutex fmut;
int fcount = 0; // Counts number of finished threads
bool finished = false;
int thread_count = std::thread::hardware_concurrency();
int limit = TSEARCH_SIZE * thread_count;
std::vector<std::thread> threads;
std::vector<std::pair<int,int>> results;
if(thread_count == 0)
{
thread_count = 4;
}
std::cout<<"Running "<<thread_count<<" threads, and solving "<<thread_count*TSEARCH_SIZE<<" numbers\n";
// Create Threads
std::vector<std::vector<std::pair<int,int>>*> help_me;
for(int i = 1; i < thread_count; i++)
{
std::vector<std::pair<int,int>>* ptr = new std::vector<std::pair<int,int>>;
help_me.push_back(ptr);
threads.push_back(std::thread(find_for, (i-1)*TSEARCH_SIZE, i*TSEARCH_SIZE,&fcount, &fmut,i,ptr));
}
// Runtime
while(!finished)
{
if(fcount == thread_count-1)
{
finished = true;
}
}
// Safely close the threads
for(std::thread& t : threads)
{
t.join();
}
for(std::vector<std::pair<int,int>>* ptr : help_me)
{
results.insert(results.end(), ptr->begin(), ptr->end());
}
// Write results to file
std::string content;
for(int i = 0; i < results.size(); i++)
{
content += std::to_string(results[i].first) + "," + std::to_string(results[i].second) + "\n";
}
std::ofstream file;
file.open("results.csv");
file << content;
file.close();
std::cout<<"A big CSV file as been generated c:\n";
auto end = std::chrono::steady_clock::now();
std::cout<<"Solving for "<<thread_count*TSEARCH_SIZE<<" numbers took "<<std::chrono::duration_cast<std::chrono::seconds>(end - start).count()<<"s\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment