pastebin - collaborative debugging tool
rovema.kpaste.net RSS


x86 RDTSCP instruction test code 1
Posted by Anonymous on Mon 17th Oct 2022 16:11
raw | new post
view followups (newest first): x86 RDTSCP instruction test code 1 by Anonymous

  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 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.  
  18. #include <pthread.h>
  19. #include <sched.h>
  20. #include <x86intrin.h>
  21.  
  22.  
  23. int main(int ac, char *av[])
  24. {
  25.         (void)puts("#start.");
  26.        
  27.         unsigned int A = 0;
  28.         unsigned long long retval = 0;
  29.         int cpu;
  30.        
  31.         /*
  32.          * The x86 rdtscp instruction and |sched_getcpu()| syscall can
  33.          * return different results when the scheduler reschedules the
  34.          * running thread, usually at the syscall boundary.
  35.          *
  36.          * Notes:
  37.          * - Using the FIFO scheduler can reduce the instances where
  38.          * this happens, but even then the scheduler can get active:
  39.          * $ time chrt --fifo 20 ksh93 -c 'while true ; do \
  40.          *      x="$(/home/rmainz/tmp/x86_rdtscp/a.out)" ; \
  41.          *      [[ "$x" == *match* ]] && break ; done ; \
  42.          * printf "res=%s\n" "$x"'
  43.          * res=#start.
  44.          * _rdtscp:        A=7, retval=43db24d4804f4e
  45.          * sched_getcpu(): cpu=3
  46.          * # mismatch A!=cpu
  47.          * #done.
  48.          * real    5m27.782s
  49.          * user    3m53.786s
  50.          * sys     1m40.138s
  51.          *
  52.          * - The only useable solution is to pin the thread to one
  53.          * cpu strand, as shown in the |USE_FIXED_CPU_NUMBER| codepath
  54.          * below...
  55.          */
  56.  
  57. #define USE_FIXED_CPU_NUMBER 1
  58. #if USE_FIXED_CPU_NUMBER
  59.         cpu_set_t cpuset;
  60.         pthread_t thread;
  61.        
  62.         thread = pthread_self();
  63.         cpu = sched_getcpu();
  64.  
  65.         CPU_ZERO(&cpuset);
  66.         CPU_SET(cpu, &cpuset);
  67.  
  68.         if (pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset) == 0)
  69.                 (void)printf("# pthread_setaffinity_np(), "
  70.                         "thread fixed to cpu %d\n",
  71.                         cpu);
  72.         else
  73.                 perror("pthread_setaffinity_np");
  74. #endif /* USE_FIXED_CPU_NUMBER */
  75.  
  76.         retval = _rdtscp(&A);
  77.         cpu = sched_getcpu();
  78.  
  79.         (void)printf("_rdtscp:\tA=%x, ", (long)A);
  80.         (void)printf("retval=%llx\n", retval);
  81.         (void)printf("sched_getcpu():\tcpu=%lx\n", (long)cpu);
  82.        
  83.         if (cpu != A)/*
  84.  * x86_rdtscp1.c - test x86 RDTSCP instruction to get the current
  85.  * CPU number
  86.  *
  87.  * Compile with:
  88.  * $ gcc -std=gnu17 -m64 x86_rdtscp1.c -lpthread
  89.  *
  90.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  91.  *
  92.  */
  93.  
  94. #define _XOPEN_SOURCE 700
  95. #define _GNU_SOURCE 1
  96.  
  97. #include <stdio.h>
  98. #include <stdlib.h>
  99.  
  100. #include <pthread.h>
  101. #include <sched.h>
  102. #include <x86intrin.h>
  103.  
  104.  
  105. int main(int ac, char *av[])
  106. {
  107.         (void)puts("#start.");
  108.        
  109.         unsigned int A = 0;
  110.         unsigned long long retval = 0;
  111.         int cpu;
  112.        
  113.         /*
  114.          * The x86 rdtscp instruction and |sched_getcpu()| syscall can
  115.          * return different results when the scheduler reschedules the
  116.          * running thread, usually at the syscall boundary.
  117.          *
  118.          * Notes:
  119.          * - Using the FIFO scheduler can reduce the instances where
  120.          * this happens, but even then the scheduler can get active:
  121.          * $ time chrt --fifo 20 ksh93 -c 'while true ; do \
  122.          *      x="$(/home/rmainz/tmp/x86_rdtscp/a.out)" ; \
  123.          *      [[ "$x" == *match* ]] && break ; done ; \
  124.          * printf "res=%s\n" "$x"'
  125.          * res=#start.
  126.          * _rdtscp:        A=7, retval=43db24d4804f4e
  127.          * sched_getcpu(): cpu=3
  128.          * # mismatch A!=cpu
  129.          * #done.
  130.          * real    5m27.782s
  131.          * user    3m53.786s
  132.          * sys     1m40.138s
  133.          *
  134.          * - The only useable solution is to pin the thread to one
  135.          * cpu strand, as shown in the |USE_FIXED_CPU_NUMBER| codepath
  136.          * below...
  137.          */
  138.  
  139. #define USE_FIXED_CPU_NUMBER 1
  140. #if USE_FIXED_CPU_NUMBER
  141.         cpu_set_t cpuset;
  142.         pthread_t thread;
  143.        
  144.         thread = pthread_self();
  145.         cpu = sched_getcpu();
  146.  
  147.         CPU_ZERO(&cpuset);
  148.         CPU_SET(cpu, &cpuset);
  149.  
  150.         if (pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset) == 0)
  151.                 (void)printf("# pthread_setaffinity_np(), "
  152.                         "thread fixed to cpu %d\n",
  153.                         cpu);
  154.         else
  155.                 perror("pthread_setaffinity_np");
  156. #endif /* USE_FIXED_CPU_NUMBER */
  157.  
  158.         retval = _rdtscp(&A);
  159.         cpu = sched_getcpu();
  160.  
  161.         (void)printf("_rdtscp:\tA=%x, ", (long)A);
  162.         (void)printf("retval=%llx\n", retval);
  163.         (void)printf("sched_getcpu():\tcpu=%lx\n", (long)cpu);
  164.        
  165.         if (cpu != A)
  166.                 (void)puts("# mismatch A!=cpu");
  167.         (void)puts("#done.");
  168.  
  169.         return EXIT_SUCCESS;
  170. }
  171.  
  172.  
  173.                 (void)puts("# mismatch A!=cpu");
  174.         (void)puts("#done.");
  175.  
  176.         return EXIT_SUCCESS;
  177. }

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