Threads

Threads - C++ - Programmation

Marsh Posté le 23-07-2003 à 11:19:37    

:sweat: salut, voila j'ai un problème:
je bosse avec Borland 4 et mon boulot est de créer une appli gérant plusieurs threads, en fait détection par caméra et ejection pneumatique en conséquence.
 
jusque là pas de problème, mais il y a deux de ces threads(sur 13 en tout), en l'occurence la détection d'image et un compteur qui mit ensemble mobilisent trop de ressources.  
 
je vous explique ça en détail:
 

  • je bosse avec une carte I/O, sur laquelle est connecté un capteur optique (le compteur) et les ejecteurs. Tout celà est géré par 1 thread compteur(de priorité higher),10 threads pour les ejecteurs(priorité lower) et 1 thread de répartition pour les ejecteurs(priorité lower).


  • de l'autre coté j'ai un thread caméra(priorité normale) qui fait de la détection d'image et qui transmet les valeurs au répartiteur.


Malheureusement tous cela mit ensemble mange trop de ressources, pour info tous les threads mit ensemble sauf celui du compteur marchent très bien.
 
Pitié donnez moi une idée!!!
Merci d'avance

Reply

Marsh Posté le 23-07-2003 à 11:19:37   

Reply

Marsh Posté le 23-07-2003 à 13:00:29    

Comment fonctionne ton thread ?
S'il n'a pas d'opération blocante, c'est normal qu'il monopolise tout. Essai d'identifier l'attente active, notamment, que fait-il entre chaque comptage ? Comment attend-il l'incrémentation suivante ?
Tu peux forcer l'ordonancement en effectuant des yield (avec SwitchToThread).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-07-2003 à 15:05:08    

en gros ton thread compteur, il scrute en permanence la carte I/O ?

Reply

Marsh Posté le 23-07-2003 à 17:13:42    

HelloWorld a écrit :

Comment fonctionne ton thread ?
S'il n'a pas d'opération blocante, c'est normal qu'il monopolise tout. Essai d'identifier l'attente active, notamment, que fait-il entre chaque comptage ? Comment attend-il l'incrémentation suivante ?
Tu peux forcer l'ordonancement en effectuant des yield (avec SwitchToThread).


 
alors mon compteur est un compteur optique type laser couplé à un ampli qui échantillonne toutes les 25 microsecondes(que je ne peut pas changer). Sachant que je tourne à 10 Hz ça me fait environ 400 prises par peignes de tapis roulant.
 
Le hic c'est que je lance mon thread qui lui va regarder sur la carte I/O les états du port X. le thread tourne tout le temps mais la boucle de traitement elle n'est activé que par un modulo[400].
 
j'ai essayé en mettant un Sleep(1) mais c'est encore pire la caméra ne détecte rien et mon compteur rate des peignes.
 
encore une chose qu'est-ce t'entends par yield??
 
Merci
 

Reply

Marsh Posté le 23-07-2003 à 18:17:24    

Citation :

Le hic c'est que je lance mon thread qui lui va regarder sur la carte I/O les états du port X. le thread tourne tout le temps mais la boucle de traitement elle n'est activé que par un modulo[400].


 
Il scrute de manière active ? J'ai pas pigé l'histoire du modulo.
Au lieu de Sleep, essaie avec SwitchToThread.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 24-07-2003 à 03:28:22    

alors je récappétes pour voir si j'ai compris:
 
1) ton capteur acquisitionne en interne à 40Khz (25µs) ?
 
2) tu veux mesurer tout les 10Hz (dumoins dixième/s) ?
   ton débit d'objets physique à trier est de 10 objets/s ?
 
heu si je comprends bien, si tu comptes 10 fois par secondes, entre chaque comptage c'est 4000 acqusition qui est fait par le capteur ?
 
j'ai bon ou je suis trop fatigué ?
 
dans tous les cas, ton thread semble choper en boucle les mesures depuis le port d'e/s, et tu fais un modulo (je crois t'avoir compris) à un endroit pour dire: yeah là j'ai un truc qui est passé devant le capteur et je dois le compter.
 
alors effectivement ça poses plusieurs problèmes:
 
un thread qui tourne en boucle sans fin à capturer, forcément ça bouffe tout le temps cpu, et en plus lorsque le noyau donne la main à un autre thread pendant un ou plusieurs timeslices, tu loupes des acquisitions matérielles qui pourront comporter des passages d'objets.
 
donc en gros quand ton thread tourne, tu peux rien faire d'autre (détection d'image non effectuée), et quand il tourne pas tu va louper des objets physiques à trier.
 
le problème viens du modèle de "communication" avec le capteur optique: pris comme ça il est tout simplement pourri, et inexploitable.
 
alors la seule solution vue l'implémentation de la communication avec le capteur serait de:
 
1) que le thread compteur chope les aquisitions que tous les 10 hz (100ms) comme ça les autres thread pourront bosser
 
2) comme le compteur ne se fera tous les 10hz, si il n'est pas calé, il va louper TOUS les objets passant devant le capteur.
il faut donc créer un système de "synchronisation".
 
pour cela, il faudrait pouvoir se caler avec le passage des objets, et dans le cas de ton implémentation matérielle de communication, la seule solution serait de boucler sans fin dans le thread compteur pour choper le premier passage d'objet, et ainsi se caler ainsi pour toutes les passages suivants.
 
donc en gros:
 
a) tous threads coupés
 
b) activation thread compteur en mode "calage" (temps cpu maximal)
 
c) une fois thread compteur "calé", tous les autres thread sont activés, et le thread compteur est mis en mode "mesure" où le thread sera, après chaque capture, mis en sommeil pour 100 ms.
l'ordonnanceur du noyau rendra alors la main aux autres threads pour bosser.
 
NOTE: évidemment il faudra faire une implémentation subtile, car le moment où le thread compteur sera rendu actif par le noyau toutes les 100ms peut très légèrement varier, le thread peut faire l'acquisition un peu trop avant ou après (et louper le passage), donc par exemple acquérir en boucle jusqu'a 5-10ms toutes les 95ms (ce qui permet de se recaller en cas de glissement d'horloge  [:necris] )
 
-------------------------
 
donc voilà c'est la seule solution que j'entrevoies avec le mode d'aquisition de ton capteur optique, pour que le thread compteur ne rate pas d'objets et qu'il ne prenne pas tout le temps cpu pour rien.
 
--------------------------
 
après si tu peux améliorer ou faire améliorer la manière de capturer ce qui viens du capteur:
 
avoir une logique qui teste pour toi ce qui passe devant le capteur et qui déclenche une interruption matérielle lors du passage d'objet. (interruption qui débloque le thread compteur par exemple)
 
ceci en faisant une lecture blocante dans le thread compteur sur un périphérique qui recevra un octet ou une donnée au moment du pasage d'un objet. (port série/parallèle ? ou carrément carte ISA ou PCI avec un asic maison :D sport ?)
 
------------------------------
 
voilà pour le moment c'est la seule contribution que je peux apporter.
 
désolé si je suis hors-sujet ou que j'ai dit des conneries  :jap:


Message édité par bjone le 24-07-2003 à 03:43:14
Reply

Marsh Posté le 24-07-2003 à 03:37:43    

sinon si techniquement ton truc c'est:
 
1) attendre le passage d'un objet  (thread compteur)
2) quand un objet passe, on lui photographie la tête (thread caméra)
3) on détecte le truc (thread caméra)
4) on décide de l'envoyer ailleurs (thread répartiteur)
5) "l'envoyer ailleurs" est effectué (thread éjecteur)
 
je pense que si "globalement" de 1 à 4, le traitement tiens pour une vitesse de 10hz, les étapes de 1 à 4 devraient être dans un boucle générale (la mise en thread est-elle réellement nécessaire ?), seul ptet le thread éjecteur si il doit programmer une séquence temporisé via la carte I/O devrait être mis en thread.
 
à toi d'évaluer les contraintes du bordel....
 
re-désolé si j'ai encore dit des conneries  :jap: (j'ai une excuse: l'heure, sinon je viens de voir Equilibrium, sympa, thème de base interressant et d'actualité, un peu de pompe sur matrix, mais ché bien chinon :D)


Message édité par bjone le 24-07-2003 à 03:40:25
Reply

Marsh Posté le 24-07-2003 à 08:14:25    

Si j ai bien compris aussi (desole j ai pris qun cafe encore), se baser sur la "precision" de l'OS quel qui soit est une heresie a mon sens tu auras toujours des derives (et pour avori a plusieurs reprise implementer des systeme d'acquisiton temps reel je peux dire que c'est pas qu'un peu la derive) dans le temps d'ou des problemes (et dans ton cas il me semble que c genant tres genant).
 
Il faut a mon sens revoir la partie hardware de ton projet et comme l'evoque bjone du cote des interruption mateielles.
Avoir une interruption materielle qui est levee a chaque fois qu'une acquisition est prete.
 
De la tu pourras "attacher" une fonction au traitement de cette interruption qui ne fait que recup la valeur dispo.
 
Si c possible tu regles tes 2 problemes : tu loupes plus rien (si ton systeme est suffisament reactif) et temps CPU pris par l acquisition nul ou presque.
 
Mais vu ta vitesse d acquisition a part cela a mon hummble avis tu vas droit dans le mur.
 
 
 
Sinon pe autre solution avec une thread suivant l implementation de ton hardware, c de mettre ue semaphor sur la valeur de ton compteur si y a possibilite que le compteur l utilise
Ca donnerait un truc comme ca

Code :
  1. void threadcapteur(void)
  2. {
  3.     while (bExit == false) {
  4.         sem_wait(&m_CapteurReady);
  5.         Je_Recup_La_Valeur_Car_Dispo
  6.         sem_post(&m_CapteurReady);
  7.         Traitement annexe de la valeur
  8.         ....
  9.     }
  10. }


 
Enfin si tu es capable de mettre une semaphore "sur" le compteur c que tu doit pouvoir mettre une interruption et la gerer donc cf la premiere partie je pense.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed