2
votes

En utilisant Boost :: Beast pour les API REST gourmandes en CPU, dois-je utiliser Async ou Sync pour les implémenter pour espérer une meilleure latence?

J'essaie d'utiliser boost :: beast pour implémenter un service Web fournissant des API REST. Ces API sont lourdes en CPU, presque sans disque ni E / S de base de données. Mon objectif est d'optimiser la latence avec un débit OK. Dois-je utiliser la méthode sync ou async pour les implémenter?

Merci!


2 commentaires

Comment allez-vous bénéficier de l'async au cas où vous n'allez pas dormir sur I / O? il suffit d'ouvrir les travailleurs en tant que nombre de processeurs et d'exécuter de manière synchrone, IMO


Je dépend vraiment de votre cas et de votre code. Async n'interdit pas la concurrence, car vous auriez simplement plusieurs threads exécutant boost :: asio :: io_context afin que vos gestionnaires puissent s'exécuter simultanément. Les brins sont une bonne méthode de synchronisation, et en suivant cette approche, vous utilisez des threads rapides pour les utilisateurs. Mais vous pouvez également simplement exécuter boost-beast sur un thread et utiliser l'un des nombreux modèles de concurrence. Mais il n'y a pas de réponse simple, je recommande la "concurrence C ++ en action" par Anthony A. Williams. Mais je parie que tout irait bien en utilisant simplement boost :: asio :: dispatch , peut-être sur un diff. io_context


3 Réponses :


1
votes

Vous pouvez tester votre manière de procéder et voir ce qui fonctionne le mieux dans votre cas d'utilisation. Utilisez ensuite des modèles de conception simultanés pour optimiser si les performances ne sont pas assez bonnes.

Je suppose que vous devriez prendre une mesure concrète de ce que vous entendez par "débit correct", puis le comparer dans votre système.


0 commentaires

1
votes

De manière générale, lorsque vous effectuez un travail intensif en E / S avec peu ou pas de surcharge CPU, sans blocage ou asynchrone est préférable. Cependant, lorsque les opérations sont gourmandes en ressources processeur, un modèle thread a tendance à avoir plus de sens.

La raison en est simple: c'est généralement une mauvaise idée de bloquer la boucle d'événements pendant de plus longues périodes - comme cela se produirait lors de l'utilisation d'un modèle asynchrone pour des calculs gourmands en CPU.

Lorsque vous commencez à bloquer la boucle d'événements, des choses comme les minuteries ne se comportent pas comme elles le devraient, puisqu'elles ne peuvent se déclencher qu'une fois que vous avez rendu le contrôle à la boucle d'événements. Ce n'est généralement pas ce que vous voulez.


0 commentaires

2
votes

Si vous voulez des délais d'expiration, vous n'avez d'autre choix que d'utiliser les API asynchrones fournies par Boost.Beast / Boost.Asio / Asio / Networking TS.


2 commentaires

Ce n'est pas strictement vrai. Vous pouvez éventuellement composer une opération asynchrone avec une minuterie (qui crée le délai d'attente) afin qu'elle bloque en appelant io_context.run () l'opération se termine. De cette façon, vous disposez d'une API synchrone avec un délai d'expiration.


Quand je dis "API asynchrone", je veux dire les interfaces fournies par Networking TS / Boost.Asio / Asio. J'ai mis à jour la réponse, merci!