Created
February 29, 2024 08:06
-
-
Save divinity76/f3c7f2ab0ab39e37e9fe36e1c666f89d to your computer and use it in GitHub Desktop.
bogostress.cpp
This file contains hidden or 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
#define _GNU_SOURCE | |
#include <iostream> | |
#include <pthread.h> | |
#include <chrono> | |
#include <vector> | |
#include <unistd.h> | |
#include <sched.h> | |
#include <stdexcept> | |
#include <climits> | |
using namespace std; | |
using namespace std::chrono; | |
static void *infiniteLoop(volatile int *arg) | |
{ | |
int core = *arg; | |
pthread_t this_thread = pthread_self(); | |
cpu_set_t cpuset = {0}; | |
CPU_SET(core, &cpuset); | |
int err = pthread_setaffinity_np(this_thread, sizeof(cpu_set_t), &cpuset); | |
if (err != 0) | |
{ | |
throw std::runtime_error("Error setting affinity for thread " + to_string(core)); | |
} | |
*arg = INT_MAX; | |
while (true) | |
{ | |
// Do nothing, forever | |
} | |
return nullptr; | |
} | |
static double calculate_bogo_mips() | |
{ | |
struct timespec start, end; | |
int64_t elapsedTime; | |
double bogoMips; | |
// Get the start time | |
clock_gettime(CLOCK_REALTIME, &start); | |
// Perform a no-op loop of 1,000,000 iterations | |
for (int i = 0; i < 1000000; ++i) | |
{ | |
// Empty loop | |
// prevent compiler from optimizing the loop | |
asm volatile("" ::: "memory"); | |
} | |
clock_gettime(CLOCK_REALTIME, &end); | |
// Calculate elapsed time in nanoseconds | |
elapsedTime = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec); | |
bogoMips = double(1e9) / double(elapsedTime); | |
return bogoMips; | |
} | |
static double bogomips_best_of(int n) | |
{ | |
double best = 0; | |
for (int i = 0; i < n; i++) | |
{ | |
double mips = calculate_bogo_mips(); | |
if (mips > best) | |
{ | |
best = mips; | |
} | |
} | |
return best; | |
} | |
static double bogo() | |
{ | |
return bogomips_best_of(3); | |
} | |
// Main program | |
int main() | |
{ | |
int numberOfCores = sysconf(_SC_NPROCESSORS_ONLN); // Get the number of cores | |
cout << "Total CPU cores available: " << numberOfCores << endl; | |
// main program is core 0 thread | |
pthread_t mainThread = pthread_self(); | |
cpu_set_t cpuset = {0}; | |
CPU_SET(0, &cpuset); | |
int err = pthread_setaffinity_np(mainThread, sizeof(cpu_set_t), &cpuset); | |
if (err != 0) | |
{ | |
throw std::runtime_error("Error setting affinity"); | |
} | |
vector<pthread_t> stress_threads; | |
for(;;){ | |
if(stress_threads.size() > numberOfCores){ | |
cout << "stress_threads.size() > numberOfCores " << endl; | |
cout << "stress_threads.size(): " << stress_threads.size() << endl; | |
cout << "numberOfCores : " << numberOfCores << endl; | |
break; | |
} | |
cout << "stressing " << stress_threads.size() << "/" << numberOfCores << " cores" << endl; | |
cout << "bogo: " << bogo() << endl; | |
pthread_t newThread; | |
volatile int core = 1 + stress_threads.size(); | |
if(core >= numberOfCores){ | |
core = 0; | |
} | |
int err = pthread_create(&newThread, nullptr, (void *(*)(void *))infiniteLoop, (void*)&core); | |
if (err != 0) | |
{ | |
throw std::runtime_error("Error creating thread " + to_string(core)); | |
} | |
pthread_detach(newThread); | |
while(core != INT_MAX){ | |
usleep(1000); | |
} | |
stress_threads.push_back(newThread); | |
} | |
for(;;){ | |
usleep(1000); | |
string str ="\r" + std::to_string(bogo()); | |
fwrite(str.c_str(), 1, str.size(), stdout); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment