pastebin - collaborative debugging tool
rovema.kpaste.net RSS


x86 RDTSCP instruction test code 1
Posted by Anonymous on Mon 17th Oct 2022 17:49
raw | new post
modification of post by Anonymous (view diff)

  1. /*
  2.  * x86_rdtscp1.c - test x86 RDTSCP instruction to get the current
  3.  * CPU number
  4.  *
  5.  * Compile with:
  6.  * $ gcc -std=gnu17 -m64 -Wall x86_rdtscp1.c -lpthread
  7.  *
  8.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  9.  *
  10.  */
  11.  
  12. #define _XOPEN_SOURCE 700
  13. #define _GNU_SOURCE 1
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18.  
  19. #include <pthread.h>
  20. #include <sched.h>
  21.  
  22. #include <x86intrin.h>
  23.  
  24.  
  25. int main(int ac, char *av[])
  26. {
  27.         (void)puts("#start.");
  28.  
  29.         unsigned int A = 0;
  30.         unsigned long long retval = 0;
  31.         int cpu;
  32.  
  33.         /*
  34.          * The x86 rdtscp instruction and |sched_getcpu()| syscall can
  35.          * return different results when the scheduler reschedules the
  36.          * running thread, usually at the syscall boundary.
  37.          *
  38.          * Notes:
  39.          * - Using the FIFO scheduler can reduce the instances where
  40.          * this happens, but even then the scheduler can get active:
  41.          * $ time chrt --fifo 20 ksh93 -c 'while true ; do \
  42.          *      x="$(/home/rmainz/tmp/x86_rdtscp/a.out)" ; \
  43.          *      [[ "$x" == *match* ]] && break ; done ; \
  44.          *      printf "res=%s\n" "$x"'
  45.          * res=#start.
  46.          * _rdtscp:        A=7, retval=43db24d4804f4e
  47.          * sched_getcpu(): cpu=3
  48.          * # mismatch A!=cpu
  49.          * #done.
  50.          * real    5m27.782s
  51.          * user    3m53.786s
  52.          * sys     1m40.138s
  53.          *
  54.          * - The only useable solution is to pin the thread to one
  55.          * cpu strand, as shown in the |USE_FIXED_CPU_NUMBER| codepath
  56.          * below...
  57.          *
  58.          * - Read https://unix4lyfe.org/benchmarking/
  59.          *
  60.          * - On some machines the cpu (strand) number is always |0|,
  61.          * independent from which CPU/strand the thread is really
  62.          * executing on... ;-(
  63.          * Current (2022-10-17) working theory is that this is the CPU ID
  64.          * of timer (the RDTSCP instruction returns a timer value!!) and
  65.          * the specific CPU only has one timer...
  66.          */
  67.  
  68. #define USE_FIXED_CPU_NUMBER 1
  69. #if USE_FIXED_CPU_NUMBER
  70.         cpu_set_t cpuset;
  71.         pthread_t thread;
  72.  
  73.         thread = pthread_self();
  74.         cpu = sched_getcpu();
  75.  
  76.         CPU_ZERO(&cpuset);
  77.         CPU_SET(cpu, &cpuset);
  78.  
  79.         if (pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset) == 0) {
  80.                 (void)printf("# pthread_setaffinity_np(), "
  81.                         "thread fixed to cpu %d\n",
  82.                         cpu);
  83.         }
  84.         else {
  85.                 /*
  86.                  * If you specify a CPU number beyond the maximum number
  87.                  * of CPUs, then |pthread_setaffinity_np()| can have a
  88.                  * |errno == 0|
  89.                  */
  90.                 perror("pthread_setaffinity_np");
  91.         }
  92. #endif /* USE_FIXED_CPU_NUMBER */
  93.  
  94.         retval = _rdtscp(&A);
  95.         cpu = sched_getcpu();
  96.  
  97.         (void)printf("_rdtscp:\tA=%x, ", A);
  98.         (void)printf("retval=%llx\n", retval);
  99.         (void)printf("sched_getcpu():\tcpu=%x\n", cpu);
  100.        
  101.         if (cpu != A)
  102.                 (void)puts("# mismatch A!=cpu");
  103.  
  104.         (void)puts("#done.");
  105.  
  106.         return EXIT_SUCCESS;
  107. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at