Question

So I basically have the ability to capture some packets from a multicast environment and I save them to file and then I multicast them out to applications which expect multicast data. I do this for simulation purposes. It's a relatively simple tool, and it has served me well when replaying 10 or even 50K packets to an application running in gdb. My replay loop looks like this:

for (size_t i = 0; i < packets_.size(); ++i)
    publisher_.publish(packets_[i].buf_, packets_[i].len_);

and the problem is that when packets_.size() is around 100-200K (I would never need to do more than that) I seem to experience packet loss when somebody is listening. I am guessing this is because they are replayed in one continuous burst. If I tried things like:

for (size_t i = 0; i < packets_.size(); ++i)
{
    if (i % Y == 0) usleep(X);
    publisher_.publish(packets_[i].buf_, packets_[i].len_);
}

for varying amounts in Y and X (like 1000/1000 and many other combos) but this doesn't work very well. My guess was that I could patch this up if I could busy chew cycles on every iteration for a very small amount of time. Busy chew because I don't want to yield to other processes and thus take longer than expected, but a very small amount, not even a millisecond because that would entail 200 seconds of waiting to multicast out the packets. Repeated calls in a loop to a sleep function seem to yield and slow me down considerably, which is why I was wondering what a simple way to spin for maybe a quarter, fifth, half, or so of a millisecond (roughly) be?

Or if there would be a better and simple way to patch this for this use case?

Was it helpful?

Solution

Function below keeps system 'busy' for some unspecified time:

static long slow( volatile long l ) {
   while ( l-- > 0 )  ;
   return l ;
}

Take some number, let's say 1000, and then run slow( N ) and at the same time count how long did it take taking clock_t t = clock() before and after call. Increase N, and repeat the same opertion until you find the number N that will keep the loop busy for 1 second. You will have now a function and a number that will keep the system busy for one second.

Hope it will help.

OTHER TIPS

Here's a busy wait loop:

#include <chrono>

auto start = std::chrono::high_resolution_clock::now();
while(std::chrono::high_resolution_clock::now()-start < std::chrono::nanoseconds(500))
    ;

The actual minimum time you can wait depends on the resolution of your implementation's high_resolution_clock. VS2012 unfortunately does not have a decent implementation yet. boost::chrono can also be used and it is much better.

If you're looking for the time to actually be random you can use the <random> library:

#include <random>

std::mt19937 eng;
std::uniform_int_distribution<> dist(200,800);

auto delay = std::chrono::nanoseconds(dist(eng));

Here's the C++11 version of usleep, for when you do want to give up the CPU.

#include <thread>

std::this_thread::sleep_for(std::chrono::nanoseconds(500));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top