Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

13 return(0.0);

14 tv_sub(&tv_stop, &tv_start);

15 clockus = tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec;

16 return(clockus);

17 }

18 int

19 touch(void *vptr, int nbytes)

20 {

21 char *cptr;

22 static int pagesize = 0;

23 if (pagesize == 0) {

24 errno = 0;

25 #ifdef _SC_PAGESIZE

26 if ((pagesize = sysconf(_SC_PAGESIZE)) == –1)

27 return(-1);

28 #else

29 pagesize = getpagesize; /* BSD */

30 #endif

31 }

32 cptr = vptr;

33 while (nbytes > 0) {

34 *cptr = 1;

35 cptr += pagesize;

36 nbytes –= pagesize;

37 }

38 return(0);

39 }

Текст

функции tv_sub приведен в листинге А.4. Она осуществляет вычитание двух структур timeval, сохраняя результат в первой структуре.

Листинг А.4. Функция tv_sub: вычитание двух структур timeval

//lib/tv_sub.c

1 #include "unpipc.h"

2 void

3 tv_sub(struct timeval *out, struct timeval *in)

4 {

5 if ((out->tv_usec –= in->tv_usec) < 0) { /* out –= in */

6 --out->tv_sec;

7 out->tv_usec += 1000000;

8 }

9 out->tv_sec –= in->tv_sec;

10 }

На компьютере Sparc под управлением Solaris 2.6 при выполнении программы пять раз подряд получим следующий результат:

solaris % bw_pipe 5 10 65536

bandwidth: 13.722 MB/sec

solaris % bw_pipe 5 10 65536

bandwidth: 13.781 MB/sec

solaris % bw_pipe 5 10 65536

bandwidth: 13.685 MB/sec

solaris % bw_pipe 5 10 65536

bandwidth: 13.665 MB/sec

solaris % bw_pipe 5 10 65536

bandwidth: 13.584 MB/sec

Каждый раз мы задаем пять циклов, 10 Мбайт за цикл и 65536 байт за один вызов write или read. Среднее от этих пяти результатов даст величину 13,7 Мбайт в секунду, приведенную в табл. А.2.

Измерение полосы пропускания очереди сообщений Posix

В листинге А.5 приведена функция main программы, измеряющей полосу пропускания очереди сообщений Posix. Листинг А.6 содержит функции reader и writer. Эта программа устроена аналогично предыдущей, измерявшей полосу пропускания канала.

ПРИМЕЧАНИЕ

Обратите внимание, что в программе приходится указывать максимальное количество сообщений в очереди при ее создании. Мы указываем значение 4. Размер канала IPC может влиять на производительность, потому что записывающий процесс может отправить это количество сообщений, прежде чем будет заблокирован в вызове mq_send, что приведет к переключению контекста на считывающий процесс.

Следовательно, производительность программы зависит от этого магического числа. Изменение его с 4 на 8 в Solaris 2.6 никак не влияет на величины, приведенные в табл. А.2, но в Digital Unix 4.0B производительность уменьшается на 12%. Мы могли ожидать, что производительность возрастет с увеличением количества сообщений в очереди, поскольку требуется в два раза меньше переключений контекста. Однако если используется отображение файла в память, это увеличивает размер отображаемого файла в два раза, как и требуемое количество памяти.

Листинг А.5. Функция main для измерения полосы пропускания очереди сообщений Posix

//bench/bw_pxmsg.c

1 #include "unpipc.h"

2 #define NAME "bw_pxmsg"

3 void reader(int, mqd_t, int);

4 void writer(int, mqd_t);

5 void *buf;

6 int totalnbytes, xfersize;

7 int

8 main(int argc, char **argv)

9 {

10 int i, nloop, contpipe[2];

11 mqd_t mq;

12 pid_t childpid;

13 struct mq_attr attr;

14 if (argc != 4)

15 err_quit("usage: bw_pxmsg <#loops> <#mbytes> <#bytes/write>");

16 nloop = atoi(argv[1]);

17 totalnbytes = atoi(argv[2]) * 1024 * 1024;

18 xfersize = atoi(argv[3]);

19 buf = Valloc(xfersize);

20 Touch(buf, xfersize);

21 Pipe(contpipe);

22 mq_unlink(Px_ipc_name(NAME)); /* error OK */

23 attr.mq_maxmsg = 4;

24 attr.mq_msgsize = xfersize;

25 mq = Mq_open(Px_ipc_name(NAME), O_RDWR | O_CREAT, FILE_MODE, &attr);

26 if ((childpid = Fork) == 0) {

27 writer(contpipe[0], mq); /* child */

28 exit(0);

29 }

30 /* 4parent */

31 Start_time;

32 for (i = 0; i < nloop; i++)

33 reader(contpipe[1], mq, totalnbytes);

34 printf("bandwidth: %.3f MB/sec\n",

35 totalnbytes / Stop_time * nloop);

36 kill(childpid, SIGTERM);

37 Mq_close(mq);

38 Mq_unlink(Px_ipc_name(NAME));

39 exit(0);

40 }

Листинг А.6. Функции reader и writer

//bench/bw_pxmsg.c

41 void

42 writer(int contfd, mqd_t mqsend)

43 {

44 int ntowrite;

45 for(;;) {

46 Read(contfd, &ntowrite, sizeof(ntowrite));

47 while (ntowrite > 0) {

48 Mq_send(mqsend, buf, xfersize, 0);

Поделиться с друзьями: