Question

I am attempting to work out the time it takes for the CPUID instruction run.

Source:

#include <stdio.h>
#include <sched.h>

cpu_set_t mask;

CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);

static inline unsigned long long tick()
{
    unsigned long long d;
    asm volatile ("rdtsc" : "=A" (d));
    return d;
}

void cpuid(void)
{
    int i;

    for(i=0; i != 5; i++)
    {
         asm volatile ("cpuid");
    }
}

int main()
{
    long long bef;
    long long aft;
    long long dif;

    bef=tick();
    cpuid();
    aft=tick();
    dif=aft-bef;

    printf("%d\n", bef);
    printf("%d\n", aft);
    printF("%d\n", dif);

    return 0;
}

Now I am compiling using the following

gcc -D_GNU_SOURCE -o test test.c

I get errors on code that isn't the file! For example:

test.c:6:1: error: expected identifier or '(' before 'do'
test.c:6:1: error: expected identifier or '(' before 'while'
test.c:7:1: error: expected identifier or '(' before '__extension__'
test.c:8:1: warning: data definition has no type or storage class [enable by def...
test.c:8:1: error: intializer element is not constant

The "def..." isn't actually the output its because my terminal windows is tiny. Im working in ESXi.

Any help would be amazing!!!

FOR FUTURE READERS

User @Iwillnotexist Idonotexist is correct in saying use the following function for full x86 & x64 support.

static __inline__ unsigned long long rdtsc(void)
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
Was it helpful?

Solution 2

These instructions should be into main():

cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);

This should fix the compilation error.

Then, five iterations for cpuid() are far too little to give meaningful results.

You can check this answer but using two sequences of different lengths made with only CPUID instructions. You need a longer cycle, but not so long that memory fetches enter into play.

I have ran some tests with TEST defined between 5 and 1000; CPU affinity did not seem to influence results on a quad-core:

#include <stdio.h>
#include <sched.h>

static inline unsigned long long tick() {
    unsigned long long d;
    asm volatile ("rdtsc" : "=A" (d));
    return d;
}

static inline void cpuid(void) {
    int i;
    for(i=0; i != TEST; i++) {
         asm volatile ("cpuid");
    }
}

int main()
{
    long long bef, aft, dif;

    bef=tick();
    cpuid();
    aft=tick();
    dif=(aft-bef)/TEST;

    printf("%lld\n", dif);

    return 0;
}

gcc -o0 -DTEST=100 -D_GNU_SOURCE -W -Wall -o time time.c && ./time

OTHER TIPS

You have code outside of a function. That's not allowed. Move the following into main:

CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top