Incidences sur les performances d’un tableau de longueur variable (C / C ++)

J’écris une fonction assez simple qui envoie un tableau à un descripteur de fichier. Cependant, pour envoyer les données, je dois append un en-tête d’un octet.

Voici une version simplifiée de ce que je fais et cela semble fonctionner:

void SendData(uint8_t* buffer, size_t length) { uint8_t buffer_to_send[length + 1]; buffer_to_send[0] = MY_SPECIAL_BYTE; memcpy(buffer_to_send + 1, buffer, length); // more code to send the buffer_to_send goes here... } 

Comme je l’ai dit, le code semble bien fonctionner. Cependant, j’ai récemment pris l’habitude d’utiliser le guide de style de Google C ++, car mon projet actuel ne contient pas de guide de style défini (je suis en fait le seul ingénieur logiciel de mon projet et je voulais utiliser quelque chose qui est utilisé dans l’indussortinge). J’ai lancé le fichier cpplint.py de Google, qui a intercepté la ligne où je crée buffer_to_send et a émis des commentaires sur le fait de ne pas utiliser de tableaux de longueur variable. Plus précisément, voici ce que le guide de style C ++ de Google a à propos des tableaux de longueur variable …

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Variable-Length_Arrays_and_alloca__

Sur la base de leurs commentaires, il semble que j’ai peut- être trouvé la cause fondamentale de collisions apparemment aléatoires dans mon code (qui se produisent très rarement, mais qui sont néanmoins agaçantes). Cependant, je suis un peu déchiré quant à la façon de le réparer.

Voici mes solutions proposées:

  1. Faites de buffer_to_send essentiellement un tableau de longueur fixe et de longueur constante. Le problème auquel je peux penser ici est que je dois rendre le tampon aussi grand que le tampon théoriquement le plus grand que je souhaite envoyer. Dans la moyenne des cas, les tampons sont beaucoup plus petits et je perdrais environ 0,5 Ko à le faire chaque fois que la fonction est appelée. Notez que le programme doit être exécuté sur un système embarqué, et bien que je ne compte pas nécessairement chaque octet, j’aimerais utiliser le moins de mémoire possible.

  2. Utilisez new et delete ou malloc / free pour allouer dynamicment le tampon. Le problème ici est que la fonction est appelée fréquemment et que le fait de demander constamment de la mémoire au système d’exploitation, puis de la libérer, entraînerait un surcoût.

  3. Utilisez deux appels successifs à write () afin de transmettre les données au descripteur de fichier. C’est-à-dire que la première écriture ne transmettrait qu’un octet et que la prochaine enverrait le rest de la mémoire tampon. Bien que cela paraisse simple, il me faudrait un peu plus de recherches sur le code (notons que ce code m’a été transmis par un ancien ingénieur qui a depuis quitté l’entreprise pour laquelle je travaille) afin de garantir que les deux écritures successives se produisent de manière atomique. De plus, si cela nécessite un locking, il devient alors de plus en plus complexe et a plus d’impact sur les performances que le cas n ° 2.

Notez que je ne peux pas faire en sorte que buffer_to_send devienne une variable membre ou qu’elle s’étende en dehors de la fonction car il existe (potentiellement) plusieurs appels à la fonction à un moment donné à partir de différents threads.

S’il vous plaît laissez-moi savoir votre opinion et ce que mon approche préférée devrait être. Merci pour votre temps.

Vous pouvez plier les deux appels successifs à write () dans votre option 3 en un seul appel à l’aide de writev ().

http://pubs.opengroup.org/onlinepubs/009696799/functions/writev.html

Je choisirais l’option 1. Si vous connaissez la longueur maximale de vos données, allouez autant d’espace (plus un octet) sur la stack à l’aide d’un tableau de taille fixe. Ce n’est pas pire que le tableau de longueur variable que vous avez montré car vous devez toujours disposer de suffisamment d’espace libre sur la stack, sinon vous ne pourrez tout simplement pas gérer votre longueur maximale (au pire, votre code planterait de façon aléatoire sur des tailles de mémoire tampon plus grandes) . Au moment où cette fonction est appelée, rien d’autre n’utilisera l’espace supplémentaire sur votre stack, il est donc prudent d’allouer un tableau de taille fixe.