Queues under Neutrino

Hi Community

I’ve try to detect the data rate of neutrino message queues.

And I have a problem in data rate, there is strong decrease
in data rate between the blocksize of 28500 byte and 29000 byte.

Results are follows:

[color=green]BLOCKSIZE: 28000 COUNTER: 12752 RATE: 69737 KByte/s
BLOCKSIZE: 28500 COUNTER: 12729 RATE: 70854 KByte/s
BLOCKSIZE: 29000 COUNTER: 1554 RATE: 8801 KByte/s

Does anybody make the same experience?

is something wrong in my little program?

start with

[color=green]./test 28000
.test 28500
./test 29000

Thank You

#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <limits.h>
#include <time.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/stat.h>
#include <sys/wait.h>

#define MAX 1000
#define PRIO MQ_PRIO_MAX
#define MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define FALSE 0
#define TRUE (!FALSE)

void sigh(int);
void berechne(FILE *datei_ptr, uint64_t SECS, uint64_t rate, char *name,
uint64_t BLOCKSIZE, volatile uint64_t counter);

volatile sig_atomic_t flag = TRUE;

int main(int argc, const char *argv[])
{
int i = 0;
size_t anz;
mqd_t tmq = 0;
int durchl = 0;
pid_t npid = 0;
FILE *datei_ptr;
uint64_t SECS = 5;
uint64_t rate = 0;
unsigned int prio;
char *senden = NULL;
char *empfang = NULL;
uint64_t BLOCKSIZE = 0;
struct mq_attr mq_attr;
char tmq_name[] = “tmq”;
char *name = “NACHQU6B.TXT”;
volatile uint64_t counter = 0;

printf(“BLOCKSIZE: %d \n”, atoi(argv[1]));
BLOCKSIZE = atoi(argv[1]);

senden = malloc(BLOCKSIZE sizeof(char)); / Heap */
empfang = malloc(BLOCKSIZE sizeof(char)); / Heap */

for (i = 0; i < BLOCKSIZE - 1; i++)
{
senden[i] = ‘x’;
empfang[i] = ‘y’;
}

senden[BLOCKSIZE - 1] = ‘\0’;
empfang[BLOCKSIZE - 1] = ‘\0’;

mq_attr.mq_maxmsg = MAX;
mq_attr.mq_msgsize = BLOCKSIZE;
mq_attr.mq_flags = 0;

if ((tmq = mq_open(tmq_name, O_CREAT | O_RDWR, MODE, &mq_attr)) == - 1)
{
printf(“Error is: %s\n”, strerror(errno));
return (EXIT_FAILURE);
}

npid = fork();

if (npid)
{
signal(SIGALRM, sigh);
alarm(SECS);

if ((tmq = mq_open(tmq_name, O_WRONLY)) ==  - 1)
{
  printf("Error is: %s\n", strerror(errno));
  return (EXIT_FAILURE);
}

while (flag)
{

  if (mq_send(tmq, senden, strlen(senden) + 1, PRIO) !=  - 1)
  {
    counter++;
  }

}

berechne(datei_ptr, SECS, rate, name, BLOCKSIZE, counter);

if (mq_close(tmq) ==  - 1)
{
  printf("Error is: %s\n", strerror(errno));
  return (EXIT_FAILURE);
}


return (EXIT_SUCCESS);

}
else
{
signal(SIGALRM, sigh);
alarm(SECS);

while (flag)
{
  if ((anz = mq_receive(tmq, empfang, strlen(empfang) + 1, &prio)) ==  - 1)
  {
    if (errno == EMSGSIZE)
    {
      printf("Message to big mq_receive \n");
      return (EXIT_FAILURE);
    }
  }
  else
  {
    //receive
  }
}

if (mq_unlink(tmq_name) != 0)
{
  printf("Error is: %s\n", strerror(errno));
  return (EXIT_FAILURE);
}

free(senden);
free(empfang);
return (EXIT_SUCCESS);

}

return (EXIT_SUCCESS);
}

void sigh(int sig_num)
{
flag = FALSE;
}

void berechne(FILE *datei_ptr, uint64_t SECS, uint64_t rate, char *name,
uint64_t BLOCKSIZE, volatile uint64_t counter)
{
rate = (counter *BLOCKSIZE) / (SECS *1024);
printf(“BLOCKSIZE: %8lld COUNTER: %8lld RATE : %8lld KByte\n”, BLOCKSIZE,
counter, rate);
datei_ptr = fopen(name, “a+”);
fprintf(datei_ptr, “BLOCKSIZE: %8lld COUNTER: %8lld RATE: %8lld KByte\n”,
BLOCKSIZE, counter, rate);

if (datei_ptr == NULL)
/* Error */
{
printf(“Error is: %s\n”, strerror(errno));
exit(EXIT_FAILURE);
}

fclose(datei_ptr);
}

My first guess would be cache size.

A few thing, strlen adding a significant load. Also you are using uint64_t where you don’t have too, 64 bit operation are significantly slower then 32 bit.

And it’s usually a bad idea to call an executable test ;-)

Also the fact that by the time you terminate each process there may be data in the queue that is left unread that is skewing the results. Instead of doing a while loop that is terminated via a signal handler, use a fix for loop and count the duration of the for loop.

Thank you mario I’ve try it

I’ve change all 64 Bit variables in 32 Bit and
change my loops in a fix for loop to counting the
time for i.e. 2000 iterations with clock_gettime().

But the result is the same,
Does anybody make the same experience?

Thank you !!

Yes Cache size could be one reason… what about further increase the size? Have you compared your results with the official QNX benchmarks from their website? If message queue speed is a problem for you, have you considered using the new ‘mq’?

Thank you Thunderblade

please explain me how to increase the Cache size
and what you are mean with using the new ‘mq’
Im starting the manager in QNX6.21 with ‘mqueue &’.
Does it gives another possibility with a new ‘mq’ ?
and how to use this

Cache is in the processor can’t do anything about it the size ;-)

Thank you!!

Yes shure, sorry stupid question
but what is mean with using the new ‘mq’
Im starting the manager in QNX6.21 with ‘mqueue &’.
Does it gives another possibility with a new ‘mq’ ?
and how to use this?

6.2.1 doesn’t have ‘mq’ - it was introduced with 6.3. You should upgrade to 6.3 SP2, I personally think it is worth it. ‘mq’ is an alternative version of ‘mqueue’, introduced with 6.3, which is faster because it uses the new, asynchronous message passing capability of 6.3.

Thank You Thunderblade!!! :mrgreen:

Hi Community

I’ve try to get the official QNX benchmark from the QNX website because
mesage queue speed is always a problem but I dont get access to this page
the message is:

Unfortunately, you do not have access to this page.
Your application to a required program has not been approved. Certain sections of the website are limited to specific customers and partners. Please refer to the requirements, listed below.

does anybody knows where I can get the benchmarks ?

Thank you !!!

I don’t think the benchmarks include ‘mq’ tests. You should try yourself on 6.3 SP2. Maybe you could also try and join the CoreOS 6.3.2 Beta program.

Hi Community !!!

I try to find the error but I think my programm is OK.

So the only possibility is, as you mentioned the cache size.

please explain me exactly how cache size of the processor is able to
affect the data rate of the message queue I dont understand this fact.

Thank you
:wink:

The mqueue server has an optimised memory allocator which is tuned for messages smaller than 28k. After 28k it falls back to malloc, which explains the drop in performance.

There is no way to tune this value.

Colin

Thank you Colin !!

please tell me more about the optimised memory allocator or
where can I find an article,
and how he is realizeed.

To my knowledge there is no article describing the allocator that is used, it’s not a published api.

Thank you Cburgess

please give me detaild information about this
“memory allocator”
malloc() will stored in the heap and
what kind of memory will be allocated for “memory allocator”, the cache?

It’s just a different heap allocator, it’s the same type of memory used.