测试进程上下文切换时间
测试Context Switch time(进程上下文切换时间)--------------------------------------------------
创建两个进程(实时进程)并在它们之间传送一个令牌,如此往返传送一定的次数。其中一个进程在读取令牌时就会引起阻塞。另一个进程发送令牌后等待其返回时也处于阻塞状态。发送令牌带来的开销与上下文切换带来的开销相比,可以忽略不计。 (利用管道传递令牌)
测试程序(1) 使用gettimeofday()获取当前时间
--------------------------------------------------
#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <time.h>#include <sched.h>#include <sys/types.h>#include <unistd.h> //pipe()int main(){ int x, i, fd, p; char send = 's'; char receive; pipe(fd); pipe(p); struct timeval tv; struct sched_param param; param.sched_priority = 0; while ((x = fork()) == -1); if (x==0) { sched_setscheduler(getpid(), SCHED_FIFO, &param); gettimeofday(&tv, NULL); printf("Before Context Switch Time %u us\n", tv.tv_usec); for (i = 0; i < 10000; i++) { read(fd, &receive, 1); write(p, &send, 1); } exit(0); } else { sched_setscheduler(getpid(), SCHED_FIFO, &param); for (i = 0; i < 10000; i++) { write(fd, &send, 1); read(p, &receive, 1); } gettimeofday(&tv, NULL); printf("After Context SWitch Time %u us\n", tv.tv_usec); } return 0;}
测试结果(进程切换时间不超过5us)
--------------------------------------------------
Before Context Switch Time 617087 us
After Context SWitch Time 702420 us
702420us - 617087us = 85333 us
85333us / 20000 = 4.26665 us
进程切换时间为4.26665 us
注: cpu MHz : 2801.042
测试程序(2) 使用rdtsc()获取当前时间
--------------------------------------------------
#include <stdio.h>#include <stdlib.h>#include <sched.h>#include <sys/types.h>#include <unistd.h>long long rdtsc(){ __asm("rdtsc");}int main(){ int x, i, fd, p; char send = 's'; char receive; pipe(fd); pipe(p); struct sched_param param; param.sched_priority = 0; while ((x = fork()) == -1); if (x==0) { sched_setscheduler(getpid(), SCHED_FIFO, &param); printf("Before Context Switch Time %lld\n", rdtsc()); for (i = 0; i < 10000; i++) { read(fd, &receive, 1); write(p, &send, 1); } exit(0); } else { sched_setscheduler(getpid(), SCHED_FIFO, &param); for (i = 0; i < 10000; i++) { write(fd, &send, 1); read(p, &receive, 1); } printf("After Context Switch Time %lld\n", rdtsc()); } return 0;}
测试结果(进程切换时间不超过5us)
--------------------------------------------------
Before Context Switch Time 16208184381648
After Context Switch Time 16208424333213
16208424333213 - 16208184381648 = 239951565(clock cycle)
239951565 * 0.357009998 ns = 85665107.74074687 ns
85665107.74074687 ns / 20000 = 4283.255387037 ns = 4.283255387037 us
注: cpu MHz : 2801.042
---------------------------------------------
2 801 042 000Hz
clock cycle = 1 000 000 000 ns / 2 801 042 000 = 0.357009998ns
查看CPU性能参数
cat /proc/cpuinfo
测试程序(3) 可直接获得进程上下文切换时间
--------------------------------------------------
#include <stdio.h>#include <stdlib.h> //drand48()#include <sched.h>#include <sys/types.h>#include <unistd.h>#include <sys/time.h> //gettimeofday()#include <time.h>typedef unsigned long long u64;double clockCycleTimeS,clockRateHZ;/* 获取当前时间,返回秒 */double second() { struct timeval tv; gettimeofday(&tv,0); return tv.tv_sec + 1e-6 * tv.tv_usec;}/* 获取当前时间,返回clock cycle */u64 rdtsc() { u64 tsc; __asm__ __volatile__("rdtsc" : "=A" (tsc)); return tsc;}/* 睡眠us微秒 */void selectsleep(unsigned us) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = us; select(0, 0, 0, 0, &tv);}/* 计算当前CPU的工作频率 */void calibrate() { double sumx = 0; double sumy = 0; double sumxx = 0; double sumxy = 0; double slope; const unsigned n = 30; unsigned i; for (i=0; i<n; i++) { double breal,real,ticks; u64 bticks; breal = second(); bticks = rdtsc(); selectsleep((unsigned)(10000 + drand48() * 200000)); ticks = rdtsc() - bticks; real = second() - breal; sumx += real; sumxx += real * real; sumxy += real * ticks; sumy += ticks; } slope = ( (sumxy - (sumx*sumy) / n) / (sumxx - (sumx*sumx) / n) ); clockRateHZ = slope; clockCycleTimeS = 1.0 / slope; printf("%3.3f MHz\n", clockRateHZ*1e-6);}int main(){ calibrate(); int x, i, p1, p2, time; char send = 's'; char receive; u64 old_time; pipe(p1); pipe(p2); pipe(time); struct sched_param param; param.sched_priority = 0; while ((x = fork()) == -1); if (x==0) { sched_setscheduler(getpid(), SCHED_FIFO, &param); old_time = rdtsc(); write(time, &old_time, sizeof(old_time)); for (i = 0; i < 10000; i++) { read(p1, &receive, 1); write(p2, &send, 1); } exit(0); } else { u64 new_time; sched_setscheduler(getpid(), SCHED_FIFO, &param); for (i = 0; i < 10000; i++) { write(p1, &send, 1); read(p2, &receive, 1); } new_time = rdtsc(); read(time, &old_time, sizeof(old_time)); printf("Latency time = %3.3f us\n", 1e6 * (new_time - old_time) * clockCycleTimeS / 20000); } return 0;}
测试结果(Linux-2.6.21 + RealTime Patch)
--------------------------------------------------
2801.226 MHz
Latency time = 8.129 us
页:
[1]