I am creating a C program that uses 100 random number generators. The number generators are split into two groups: ones that create 100 numbers and ones that create 10 000 000 numbers.
I am trying to see the difference between:
- Using deferred launching for the 100 numbers and async for the 10 000 000 numbers.
- Using only async for both types of number generators.
There's no difference in time, so my code has something wrong with it, but so far I haven't been able to find it because I am a beginner with C .
Below is the code. I've commented the part that uses only async.
#include <iostream>
#include <chrono>
#include <future>
#include <list>
/*
Using both deferred and async launchings: 5119 ms
Using only async launching: 5139 ms
*/
using namespace std;
class RandomNumberGenerator
{
public:
enum class task { LIGHT, HEAVY };
task taskType;
RandomNumberGenerator(): taskType(task::LIGHT)
{
int rnd = rand() % 2;
if (rnd == 0)
{
taskType = task::LIGHT;
}
else
{
taskType = task::HEAVY;
}
}
bool generateNumbers()
{
int number;
if(taskType == task::LIGHT)
{
for (int i = 0; i < 100; i )
{
number = rand();
}
}
else
{
for (int i = 0; i < 1000000; i )
{
number = rand();
}
}
return true;
}
};
int main()
{
cout << "Starting to generate numbers\n";
RandomNumberGenerator objects[100];
auto start = chrono::system_clock::now();
for (int i = 0; i < 100; i )
{
objects[i].generateNumbers();
future<bool> gotNumbers;
if (objects[i].taskType == RandomNumberGenerator::task::LIGHT)
{
gotNumbers = async(launch::deferred, &RandomNumberGenerator::generateNumbers, &objects[i]);
}
else
{
gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
}
bool result = gotNumbers.get();
//future<bool> gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
//bool result = gotNumbers.get();
}
auto end = chrono::system_clock::now();
cout << "Total time = " << chrono::duration_cast<chrono::milliseconds>(end - start).count() << " seconds\n";
}
CodePudding user response:
using launch::deferred
or launch::async
the same amount of work still needs to be done the only difference is whether it is done on another thread and the current thread blocks waiting for that thread to finish when you call gotNumbers.get()
or whether the result is calculated directly in the current thread when you call gotNumbers.get()
. Either way you aren't gaining any performance by using additional threads as only one thread is ever executing at a time.
If you start executing the async work before calling objects[i].generateNumbers()
you might see more difference (though the overhead of std::async might still outweigh the performance increase).
#if 1
future<bool> gotNumbers;
if ( objects[ i ].taskType == RandomNumberGenerator::task::LIGHT )
{
gotNumbers = async( launch::deferred, &RandomNumberGenerator::generateNumbers, &objects[ i ] );
}
else
{
gotNumbers = async( launch::async, &RandomNumberGenerator::generateNumbers, &objects[ i ] );
}
#else
future<bool> gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
#endif
objects[ i ].generateNumbers();
bool result = gotNumbers.get();