Измерение полосы пропускания очереди сообщений 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/sec ",

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 }

Данный текст является ознакомительным фрагментом.