Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving timing precision on Linux #419

Open
erlingrj opened this issue May 3, 2024 · 0 comments
Open

Improving timing precision on Linux #419

erlingrj opened this issue May 3, 2024 · 0 comments

Comments

@erlingrj
Copy link
Collaborator

erlingrj commented May 3, 2024

I got a really good tip from Henrik which is that you can prevent the CPU from changing c-states and greatly improve the wakeup accuracy.
I don't understand the details of why keeping this specific file descriptor open does the trick and how portable it is, but Linux-users can try it out themselves:

This might be interesting for @soyerefsane

target C;

reactor Default {
  timer t(0, 100 msec)
  reaction(t) {=
    lf_print(PRINTF_TIME, lf_time_physical() - lf_time_logical());
  =}
}

reactor RT extends Default {
  reaction(startup) {=
    lf_scheduling_policy_t cfg;
    cfg.policy = LF_SCHED_PRIORITY;
    cfg.priority = 99;
    int res = lf_thread_set_scheduling_policy(lf_thread_self(), &cfg);
    if (res != 0) {
      lf_print_error_and_exit("lf_thread_set_scheduling_policy failed with %d", res);
    }
  =}
}

reactor CStatesRT extends Default {
  preamble {=
    #include <fcntl.h>
    #include <errno.h>
  =}
  state dma_lat_fd:int = -1
  reaction(startup) {=
    lf_scheduling_policy_t cfg;
    cfg.policy = LF_SCHED_PRIORITY;
    cfg.priority = 99;
    int res = lf_thread_set_scheduling_policy(lf_thread_self(), &cfg);
    if (res != 0) {
      lf_print_error_and_exit("lf_thread_set_scheduling_policy failed with %d", res);
    }
    /* disable dma latency, this avoids c-state transitions */
	  self->dma_lat_fd = open("/dev/cpu_dma_latency", O_RDWR);
	  if (self->dma_lat_fd >= 0) {
      int lat_val = 0;
      int wres = write(self->dma_lat_fd, &lat_val, sizeof(lat_val));
      if (wres < 1) {
        lf_print_error_and_exit("Failed writing %d to /dev/cpu_dma_latency (%d)",
          lat_val, errno);
      }
    } else {
      lf_print_error_and_exit("Failed to open cpu_dma_latency (%d)", self->dma_lat_fd);
    }
  =}

  reaction(shutdown) {=
    if (self->dma_lat_fd) {
      int res = close(self->dma_lat_fd);
      if (res != 0) {
        lf_print_error_and_exit("Failed to close cpu_dma_latency (%d)", res);
      }
    }
  =}
}


main reactor {
  // r = new Default()
 // r = new RT()
  r = new CStatesRT()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant