测试Context Switch time(进程上下文切换时间)
--------------------------------------------------
创建两个进程(实时进程)并在它们之间传送一个令牌,如此往返传送一定的次数。其中一个进程在读取令牌时就会引起阻塞。另一个进程发送令牌后等待其返回时也处于阻塞状态。发送令牌带来的开销与上下文切换带来的开销相比,可以忽略不计。 (利用管道传递令牌)
测试程序(1) 使用gettimeofday()获取当前时间
--------------------------------------------------
测试结果(进程切换时间不超过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()获取当前时间
--------------------------------------------------
测试结果(进程切换时间不超过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) 可直接获得进程上下文切换时间
--------------------------------------------------
测试结果(Linux-2.6.21 + RealTime Patch)
--------------------------------------------------
2801.226 MHz
Latency time = 8.129 us
--------------------------------------------------
创建两个进程(实时进程)并在它们之间传送一个令牌,如此往返传送一定的次数。其中一个进程在读取令牌时就会引起阻塞。另一个进程发送令牌后等待其返回时也处于阻塞状态。发送令牌带来的开销与上下文切换带来的开销相比,可以忽略不计。 (利用管道传递令牌)
测试程序(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[2], p[2];
- 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, ¶m);
- gettimeofday(&tv, NULL);
- printf("Before Context Switch Time %u us\n", tv.tv_usec);
- for (i = 0; i < 10000; i++) {
- read(fd[0], &receive, 1);
- write(p[1], &send, 1);
- }
- exit(0);
- }
- else {
- sched_setscheduler(getpid(), SCHED_FIFO, ¶m);
- for (i = 0; i < 10000; i++) {
- write(fd[1], &send, 1);
- read(p[0], &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[2], p[2];
- 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, ¶m);
- printf("Before Context Switch Time %lld\n", rdtsc());
- for (i = 0; i < 10000; i++) {
- read(fd[0], &receive, 1);
- write(p[1], &send, 1);
- }
- exit(0);
- }
- else {
- sched_setscheduler(getpid(), SCHED_FIFO, ¶m);
- for (i = 0; i < 10000; i++) {
- write(fd[1], &send, 1);
- read(p[0], &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[2], p2[2], time[2];
- 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, ¶m);
- old_time = rdtsc();
- write(time[1], &old_time, sizeof(old_time));
- for (i = 0; i < 10000; i++) {
- read(p1[0], &receive, 1);
- write(p2[1], &send, 1);
- }
- exit(0);
- }
- else
- {
- u64 new_time;
- sched_setscheduler(getpid(), SCHED_FIFO, ¶m);
- for (i = 0; i < 10000; i++) {
- write(p1[1], &send, 1);
- read(p2[0], &receive, 1);
- }
- new_time = rdtsc();
- read(time[0], &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
原文连接:http://ocelot1985-163-com.iteye.com/blog/1029949