Skip to content

Instantly share code, notes, and snippets.

@fabiolimace
Last active August 15, 2023 15:54
Show Gist options
  • Save fabiolimace/89a0295e34b4e256266d42a8a3ae5082 to your computer and use it in GitHub Desktop.
Save fabiolimace/89a0295e34b4e256266d42a8a3ae5082 to your computer and use it in GitHub Desktop.
Measure the duration to get 1 billion milliseconds using div and shift separately
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
// comparison baseline
long get_seconds(void)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return tp.tv_sec;
}
// used for benchmarking
long get_microseconds(void)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return ((tp.tv_sec * 1000000) + (tp.tv_nsec / 1000L));
}
long get_milliseconds_using_div(void)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L));
}
long get_milliseconds_using_shift(void)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return ((tp.tv_sec << 10) | (tp.tv_nsec >> 20));
}
void measure_duration()
{
long start = 0L;
long end = 0L;
start = get_microseconds();
for(int i = 0; i < 1<<30 ; i++) get_seconds();
end = get_microseconds();
printf("duration to get seconds (baseline): %f s\n", (end - start) / 1000000.0);
start = get_microseconds();
for(int i = 0; i < 1<<30 ; i++) get_milliseconds_using_div();
end = get_microseconds();
printf("duration to get milliseconds using div: %f s\n", (end - start) / 1000000.0);
start = get_microseconds();
for(int i = 0; i < 1<<30 ; i++) get_milliseconds_using_shift();
end = get_microseconds();
printf("duration to get milliseconds using shift: %f s\n", (end - start) / 1000000.0);
}
int main()
{
measure_duration(); // measure the time for 1 billion timestamps
}
@fabiolimace
Copy link
Author

fabiolimace commented Aug 7, 2023

OUTPUT:

user@computer:~$ gcc -O0 measure_duration_get_milliseconds.c && ./a.out 
duration to get seconds (baseline):       17.180221 s
duration to get milliseconds using div:   17.571193 s
duration to get milliseconds using shift: 17.187412 s
user@computer:~$ gcc -O0 measure_duration_get_milliseconds.c && ./a.out 
duration to get seconds (baseline):       16.747078 s
duration to get milliseconds using div:   18.128598 s
duration to get milliseconds using shift: 17.042408 s
user@computer:~$ gcc -O0 measure_duration_get_milliseconds.c && ./a.out 
duration to get seconds (baseline):       16.958577 s
duration to get milliseconds using div:   17.956647 s
duration to get milliseconds using shift: 17.617555 s

@fabiolimace
Copy link
Author

Assembly difference between division and shift:

user@computer:~$ diff get_milliseconds_with_div.s get_milliseconds_with_shift.s 
23,33c23,27
< 	imulq	$1000, %rax, %rsi
< 	movq	-24(%rbp), %rcx
< 	movabsq	$4835703278458516699, %rdx
< 	movq	%rcx, %rax
< 	imulq	%rdx
< 	movq	%rdx, %rax
< 	sarq	$18, %rax
< 	sarq	$63, %rcx
< 	movq	%rcx, %rdx
< 	subq	%rdx, %rax
< 	addq	%rsi, %rax
---
> 	salq	$10, %rax
> 	movq	%rax, %rdx
> 	movq	-24(%rbp), %rax
> 	sarq	$20, %rax
> 	orq	%rdx, %rax

@x4m
Copy link

x4m commented Aug 15, 2023

Well, 5% difference is a big deal, actually.
Many thanks for your work on these benchmarks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment