Created
November 5, 2011 22:07
-
-
Save zed/1342088 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CFLAGS = -O2 -g \ | |
-D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \ | |
-std=c99 -Wall -Wextra -pedantic \ | |
-Wunused -Wimplicit -Wshadow -Wformat=2 \ | |
-Wmissing-declarations -Wno-missing-prototypes -Wwrite-strings \ | |
-Wbad-function-cast -Wnested-externs -Wcomment -Winline \ | |
-Wchar-subscripts -Wcast-align \ | |
-Wsequence-point \ | |
LDFLAGS = | |
LIBS = -lrt -lm | |
.PHONY: all | |
all: USE_SEM USE_SIG USE_PIPE USE_SOCKET USE_BUSY | |
USE_%: test_method.c | |
@$(CC) $(CFLAGS) -D$@ -c -o $<.o $< | |
@$(CC) $(LDFLAGS) -o $@ $<.o $(LIBS) | |
@rm $<.o | |
@printf "%8s %17s %8s %8s\n" "$@ us" mean median '%95' | |
@for i in 1 10 100 1000 10000; do ./$@ $$i 1 ;done | |
@rm $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
USE_SEM us mean median %95 | |
1 3.61 ±4.9 2.27 5.24 | |
10 3.53 ±7.0 2.24 4.15 | |
100 24.31 ±6.7 25.21 29.63 | |
1000 38.61 ±20.5 29.71 72.33 | |
10000 64.85 ±16.5 64.71 84.10 | |
USE_SIG us mean median %95 | |
1 3.16 ±4.4 2.51 4.07 | |
10 6.36 ±7.3 4.02 27.97 | |
100 24.82 ±7.1 25.73 30.47 | |
1000 44.55 ±21.1 39.70 73.47 | |
10000 68.22 ±16.3 65.87 94.72 | |
USE_PIPE us mean median %95 | |
1 5.63 ±8.4 3.62 20.48 | |
10 5.32 ±7.6 3.66 9.49 | |
100 38.49 ±23.0 28.08 78.91 | |
1000 43.80 ±50.8 38.46 70.39 | |
10000 70.09 ±12.0 66.33 94.59 | |
USE_SOCKET us mean median %95 | |
1 7.22 ±10.2 5.07 25.73 | |
10 9.35 ±60.0 5.07 27.79 | |
100 29.89 ±14.2 30.43 42.54 | |
1000 39.76 ±16.9 40.92 60.87 | |
10000 72.26 ±99.5 70.69 116.12 | |
USE_BUSY us mean median %95 | |
1 0.15 ±0.0 0.15 0.22 | |
10 0.19 ±0.4 0.12 0.36 | |
100 0.17 ±0.5 0.17 0.20 | |
1000 0.26 ±1.9 0.19 0.29 | |
10000 0.28 ±0.2 0.23 0.57 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#include <stdio.h> | |
#include <time.h> | |
int main() { | |
struct timespec start, end; | |
if (clock_gettime(CLOCK_REALTIME, &start) < 0) | |
perror("start"); | |
double d = sqrt(4.); | |
if (clock_gettime(CLOCK_REALTIME, &end) < 0) | |
perror("end"); | |
printf("%ld %ld ", (long)(end.tv_sec-start.tv_sec), | |
(long)(end.tv_nsec-start.tv_nsec)); | |
printf("%.0lf\n", d); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <assert.h> | |
#include <stdio.h> | |
#include <semaphore.h> | |
#include <unistd.h> | |
#include <sched.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/mman.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/socket.h> | |
#include <time.h> | |
#include <signal.h> | |
#include <math.h> | |
void wake(); | |
void hiber(); | |
void init(); | |
#define AVERAGE_ON 1000 | |
#define WARMUP 100 | |
long long int nsecs[AVERAGE_ON]; | |
static | |
int icomp(void const *vl,void const *vr) | |
{ | |
long long int const *l = vl; | |
long long int const *r = vr; | |
return *l - *r; | |
} | |
struct timespec *ts; | |
volatile int *ready; | |
char *shmem; | |
static | |
void init_shared() | |
{ | |
void *p = mmap(0,4096,PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,0,0); | |
assert(p!=MAP_FAILED); | |
shmem = p; | |
ts = (void*)(shmem+0); | |
ready = (void*)(shmem+128); | |
shmem+=1024; | |
} | |
int do_affin; | |
static | |
void affin(int id) | |
{ | |
if(!do_affin) | |
return; | |
cpu_set_t set; | |
CPU_ZERO(&set); | |
CPU_SET(id,&set); | |
assert(sched_setaffinity(getpid(),sizeof(set),&set)==0); | |
} | |
int sleep_time; | |
static | |
void do_sleep() | |
{ | |
struct timespec tm = { .tv_sec = 0 , .tv_nsec = sleep_time * 1000}; | |
nanosleep(&tm,0); | |
/* | |
struct timespec now,next; | |
clock_gettime(CLOCK_REALTIME,&now); | |
next = now; | |
next.tv_nsec += sleep_time * 1000; | |
static const long long million = 1000*1000*1000; | |
if(next.tv_nsec >= million) { | |
next.tv_sec += next.tv_nsec / million; | |
next.tv_nsec -= next.tv_nsec / million * million; | |
} | |
do { | |
clock_gettime(CLOCK_REALTIME,&now); | |
} while(now.tv_sec < next.tv_sec || (now.tv_sec == next.tv_sec && now.tv_nsec < next.tv_nsec)); | |
*/ | |
} | |
int main(int argc,char **argv) | |
{ | |
init_shared(); | |
init(); | |
assert(argc==3); | |
sleep_time = atoi(argv[1]); | |
do_affin = atoi(argv[2]); | |
int r = fork(); | |
int i; | |
if(r == 0) { | |
affin(0); | |
for(i=-WARMUP;i<AVERAGE_ON;i++) { | |
do { | |
do_sleep(); | |
}while(!*ready); | |
*ready = 0; | |
clock_gettime(CLOCK_REALTIME,ts); | |
wake(); | |
} | |
return 0; | |
} | |
else { | |
affin(1); | |
for(i=-WARMUP;i<AVERAGE_ON;i++) { | |
*ready = 1; | |
hiber(); | |
struct timespec now; | |
clock_gettime(CLOCK_REALTIME,&now); | |
if(i>=0) { | |
nsecs[i] = (now.tv_sec - ts->tv_sec) * (1000LL * 1000 * 1000) + | |
(now.tv_nsec - ts->tv_nsec); | |
} | |
} | |
qsort(nsecs,AVERAGE_ON,sizeof(long long),icomp); | |
long long total = 0; | |
for(i=0;i<AVERAGE_ON;i++) | |
total+=nsecs[i]; | |
total /= AVERAGE_ON; | |
double std = 0; | |
for(i=0;i<AVERAGE_ON;i++) | |
std+=(total - nsecs[i])*(total - nsecs[i]); | |
std = sqrt(std/AVERAGE_ON) ; | |
printf(" %8d %8.2f ±%-8.1f %8.2f %8.2f\n", | |
sleep_time, | |
total/1e3, | |
std/1e3, | |
nsecs[AVERAGE_ON/2]/1e3, | |
nsecs[AVERAGE_ON / 100 * 95]/1e3); | |
/*printf("Min - %8.2f\n",nsecs[0]/1e3); | |
printf("Med - %8.2f\n",nsecs[AVERAGE_ON/2]/1e3); | |
printf("90%% - %8.2f\n",nsecs[AVERAGE_ON / 10 * 9]/1e3); | |
printf("95%% - %8.2f\n",nsecs[AVERAGE_ON / 100 * 95]/1e3); | |
printf("99%% - %8.2f\n",nsecs[AVERAGE_ON / 100 * 99]/1e3); | |
printf("Max - %8.2f\n",nsecs[AVERAGE_ON - 1]/1e3);*/ | |
int st=0; | |
wait(&st); | |
} | |
return 0; | |
} | |
#ifdef USE_SEM | |
void init() | |
{ | |
assert(sem_init((sem_t*)shmem,1,0)==0); | |
} | |
void wake() | |
{ | |
sem_post((sem_t*)shmem); | |
} | |
void hiber() | |
{ | |
sem_wait((sem_t*)shmem); | |
} | |
#elif defined USE_SIG | |
int pid; | |
void init() | |
{ | |
sigset_t set; | |
sigemptyset(&set); | |
sigaddset(&set,SIGUSR1); | |
sigprocmask(SIG_BLOCK,&set,0); | |
} | |
void wake() | |
{ | |
if(pid == 0) | |
pid =getppid(); | |
union sigval sv; | |
memset(&sv,0,sizeof(sv)); | |
sigqueue(pid,SIGUSR1,sv); | |
} | |
void hiber() | |
{ | |
sigset_t set; | |
sigemptyset(&set); | |
sigaddset(&set,SIGUSR1); | |
//int sig; | |
//sigwait(&set,&sig); | |
siginfo_t inf; | |
sigwaitinfo(&set,&inf); | |
} | |
#elif defined(USE_PIPE) | |
int pipes[2]; | |
void init() | |
{ | |
assert(pipe(pipes)==0); | |
} | |
void wake() | |
{ | |
assert(write(pipes[1],"A",1)==1); | |
} | |
void hiber() | |
{ | |
char c; | |
assert(read(pipes[0],&c,1)==1); | |
} | |
#elif defined USE_SOCKET | |
int pipes[2]; | |
void init() | |
{ | |
assert(socketpair(AF_UNIX,SOCK_STREAM,0,pipes)==0); | |
} | |
void wake() | |
{ | |
assert(write(pipes[1],"A",1)==1); | |
} | |
void hiber() | |
{ | |
char c; | |
assert(read(pipes[0],&c,1)==1); | |
} | |
#elif defined USE_BUSY | |
void init() | |
{ | |
} | |
void wake() | |
{ | |
volatile char *p = shmem; | |
*p = 0; | |
__sync_synchronize(); | |
} | |
void hiber() | |
{ | |
volatile char *p = shmem; | |
*p = 1; | |
__sync_synchronize(); | |
while(*p!=0) { | |
__sync_synchronize(); | |
} | |
} | |
#else | |
#error "No method defined" | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment