測試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[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 javascript