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

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

Измерение полосы пропускания очереди сообщений 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/secn",
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);
49    ntowrite –= xfersize;
50   }
51  }
52 }
53 void
54 reader(int contfd, mqd_t mqrecv, int nbytes)
55 {
56  ssize_t n;
57  Write(contfd, &nbytes, sizeof(nbytes));
58  while ((nbytes > 0) &&
59   ((n = Mq_receive(mqrecv, buf, xfersize, NULL)) > 0)) {
60   nbytes –= n;
61  }
62 }

Оглавление книги


Генерация: 1.254. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз