Bryan Fok
Bryan Fok

Reputation: 3487

boost::asio::strand post method performance

I was measuring the performance from thread A post an event to the strand, until the strand begin to process it. I was presumed that for the different number of receive packets, 500 ,or 1 from the below example, wouldn't impact to the boost::asio::strand when it would receive the packets, because I was just passing the pointer to the packets array packets_ptr to the strand, I believe no copying was involved. However,after I timed 9999999 iteration individually, results shows they aren't even similar between different size. for the size of 1, it always take between 1~9micro sec, and for the size of 500, its bwetween 50 ~85micro sec.

//Socket Thread     
int packet_count = recvmmsg(mcast_fd, packets, 500, 0, NULL); //OR
    int packet_count = recvmmsg(mcast_fd, packets, 1, 0, NULL);
    .....
    packets_recv_time = timer.getTime();
    strand_.post(boost::bind(&handler_class::process_package_method, this, packets_ptr, packets_recv_time, num_of_packets));
    .....

//io_service thread
    handler_class::process_package_method(...)
    {
    prcess_beign_time = timer.getTime();
    Measure_time = prcess_beign_time - packets_recv_time;
    }

Upvotes: 2

Views: 2259

Answers (1)

Tanner Sansbury
Tanner Sansbury

Reputation: 51891

The presumptions are correct. However, the analytics are wrong. The timestamps are not measuring the performance of strand::post(). Instead, they are measuring the duration of when a completion handler is posted into a strand, and when the io_service starts execution of the completion handler, which is affected by numerous factors (threads, current work load, current strand backlog, etc).

To measure the performance of strand::post(), one would need to sample immediately before and after the post:

auto t1 = clock::now();
strand_.post(...);
auto t2 = clock::now();

When a handler is posted into a strand, it may be copied or moved before it is executed. Hence, if a user provided handler's copy/move construction has a uniform cost, then the performance of strand::post() will be fairly constant. Variance can be introduced when:

  • The handler's copy/move construction does not have a uniform cost. For instance, if a vector was bound to the handler, then copy construction will be affected by the amount of elements being copied.
  • There are multiple threads concurrently changing the strand's internals. As the strand provides thread safety, thread contention may occur within strand::post().

In the original code, the functor returned from boost::bind() has the same type regardless of the amount of messages that have been received. Furthermore, it and its bound arguments have a uniform copy/move construction cost. Thus, the amount of messages received will not affect the performance of strand::post().

Upvotes: 4

Related Questions