Re: [RFC PATCH V2 2/9] perf: Extend ABI to support post-processing monotonic raw conversion

From: Liang, Kan
Date: Tue Feb 14 2023 - 15:38:43 EST




On 2023-02-14 3:11 p.m., John Stultz wrote:
> On Tue, Feb 14, 2023 at 9:00 AM Liang, Kan <kan.liang@xxxxxxxxxxxxxxx> wrote:
>> On 2023-02-14 9:51 a.m., Liang, Kan wrote:
>>> If I understand correctly, the idea is to let the user space tool run
>>> the above interpoloation algorithm several times to 'guess' the atomic
>>> mapping. Using the mapping information to covert the TSC from the PEBS
>>> record. Is my understanding correct?
>>>
>>> If so, to be honest, I doubt we can get the accuracy we want.
>>>
>>
>> I implemented a simple test to evaluate the error.
>
> Very cool!
>
>> I collected TSC -> CLOCK_MONOTONIC_RAW mapping using the above algorithm
>> at the start and end of perf cmd.
>> MONO_RAW TSC
>> start 89553516545645 223619715214239
>> end 89562251233830 223641517000376
>>
>> Here is what I get via mult/shift conversion from this patch.
>> MONO_RAW TSC
>> PEBS 89555942691466 223625770878571
>>
>> Then I use the time information from start and end to create a linear
>> function and 'guess' the MONO_RAW of PEBS from the TSC. I get
>> 89555942692721.
>> There is a 1255 ns difference.
>> I tried several different PEBS records. The error is ~1000ns.
>> I think it should be an observable error.
>
> Interesting. That's a good bit higher than I'd expect as I'd expect a
> clock_gettime() call to take ~ double digit nanoseconds range on
> average, so the error should be within that.
>
> Can you share your logic?
>

I run the algorithm right before and after the perf command as below.
(The source code of time is attached.)

$./time
$perf record -e cycles:upp --clockid monotonic_raw $some_workaround
$./time

The time will dump both MONO_RAW and TSC. That's where "start" and "end"
from.
The perf command print out both TSC and converted MONO_RAW (using the
mul/shift from this patch series). That's where "PEBS" value from.

Than I use the below formula to calculate the guessed MONO_RAW of PEBS TSC.
Guessed_MONO_RAW = (PEBS_TSC - start_TSC) / (end_TSC - start_TSC) *
(end_MONO_RAW - start_MONO_RAW) + start_MONO_RAW.

The guessed_MONO_RAW is 89555942692721.
The PEBS_MONO_RAW is 89555942691466.
The difference is 1255.

Is the calculation correct?

Thanks,
Kan#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>

static inline unsigned long rdtsc ()
{
unsigned long var;
unsigned int hi, lo;

asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
var = ((unsigned long long int) hi << 32) | lo;

return var;
}

typedef unsigned long long u64;

int main()
{
struct timespec ts;
u64 start, end, delta, mid;
do {
start= rdtsc();
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
end = rdtsc();
delta = end-start;
} while (delta > 20000); // make sure the reads were not preempted
mid = start + (delta +(delta/2))/2; //round-closest
printf("%llu %llu %llu\n", start, end, delta);
printf("MONO_RAW: %llu TSC: %llu\n", (u64)ts.tv_sec * 1000000000 + ts.tv_nsec, mid);
}