Skip to content

rpc latency suddenly increases when client sleeps for a while after rpc call #104

@jiangxiaosheng

Description

@jiangxiaosheng

Hi,

When I ported eRPC to my system, I measured the latency of the RPC call and surprisingly found it to be very high (up to 10s of ms). To reproduce the results, here is the simplified program based on the hello_world example.

#include <thread>
#include <chrono>
erpc::Rpc<erpc::CTransport> *rpc;
erpc::MsgBuffer req;
erpc::MsgBuffer resp;

#define enable_timer std::chrono::time_point<std::chrono::system_clock> _st, _et
#define start_timing  _st = std::chrono::system_clock::now()
#define end_timing(msg, args...)  do {  \
    _et = std::chrono::system_clock::now(); \
    double _elapsed = (double) std::chrono::duration_cast<std::chrono::nanoseconds>(_et - _st).count() / 1000000; \
    printf("[%.3fms] " msg "\n", _elapsed, ##args);  \
  } while (0)

void cont_func(void *, void *t) { 
  // printf("%s\n", resp.buf_);
  auto done = static_cast<bool *>(t);
  *done = true;
}

void sm_handler(int, erpc::SmEventType, erpc::SmErrType, void *) {}

int main() {
  std::string client_uri = kClientHostname + ":" + std::to_string(kUDPPort);
  erpc::Nexus nexus(client_uri);

  rpc = new erpc::Rpc<erpc::CTransport>(&nexus, nullptr, 0, sm_handler);

  std::string server_uri = kServerHostname + ":" + std::to_string(kUDPPort);
  int session_num = rpc->create_session(server_uri, 0);

  while (!rpc->is_connected(session_num)) rpc->run_event_loop_once();

  req = rpc->alloc_msg_buffer_or_die(kMsgSize);
  resp = rpc->alloc_msg_buffer_or_die(kMsgSize);

  enable_timer;
  for (int i = 0; i < 100; i++) {
    start_timing;
    bool done = false;
    rpc->enqueue_request(session_num, kReqType, &req, &resp, cont_func, static_cast<void *>(&done));
    while (!done) rpc->run_event_loop_once();
    end_timing("rpc latency");
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }

  delete rpc;
}

So if you comment out the sleep function after the rpc call, the results are good - ~10us avg latency. However, if you do not, the latency rises up to 370us. And furthermore, if you sleep longer, like 100ms, the latency then increases to 4.5ms.

I've done some debugging on eRPC and found out that if I do sleep, there are re-transmissions for each request and it seems likely to be the reason for the latency issue.

I think this pattern should be very common though: user calls an RPC, does some processing (which may take some time as I simulated by a sleep), and repeats. Is it a bug or a feature? If it's a feature, how would you suggest I handle my use case? Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions