struktura producent konsument - rozmiar bufora

Tematy związane z tworzeniem dużych aplikacji. Zaganiednia dotyczące architektury oraz zasad tworzenia optymalnych rozwiązań.
MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 13 kwie 2017 11:22

Witam.
W projekcie muszę zmniejszyć okno akwizycji przez co pętla producenta działa szybciej (stała częstotliwość próbkowania)
jednak kod w pętli konsumenta mimo, iż ma mniej danych nie działa dużo szybciej
w wyniku tego kolejka przepełnia się.
Testowałem rozwiązanie przedstawione w pliku (z odczytem i czyszczeniem wielu elementów)
jednak w przypadku (produkcja co 100ms, konsumpcja co 2400ms, rozmiar bufora 15) nie dochodzi do nadpisywania elementów w kolejce.
Generalnie producent wrzuca 24 elementy między kolejnymi odczytami, bufor jest 15 elementowy więc 9 powinno zostać nadpisane.
W teście nic takiego nie dzieje się, i mimo, że "liczba elementów" wskazuje wartość 15 to "tablica elementów"
w konsumencie zawiera wszystkie elementy.
Jakoś intuicyjnie nie ufam temu. Dlaczego nie dochodzi do nadpisywania elementów?
W jakiej sytuacji może dojść?
Mogę zwiększyć bufor lub zmniejszyć opóźnienie konsumenta, ale w teście chciałem sprawdzić przypadek błędny.
Dodatkowo, klaster błędu nie zwraca żadnego błędu przepełnienia.

W docelowym kodzie w kolejce znajduje się klaster zawierający tablice waveformów, których wolałbym nie gubić.
Pytanie przy okazji:
Czy jest może jakieś lepsze rozwiązanie na wyciągnięcie więcej niż jednego elementu z kolejki?

Pozdrawiam
Zuk
Załączniki
producer consumer test.png

TMa
Posty: 198
Rejestracja: 07 sty 2010 12:56
Wersja środowiska: LabVIEW 2017
Been thanked: 3 times

Re: struktura producent konsument - rozmiar bufora

Post autor: TMa » 13 kwie 2017 12:19

Nie obsługujesz wejść 'timeout in ms' oraz wyjść 'timed out?' z funkcji 'Enqueue/Dequeue Element Function'. Przy wrzucaniu danych do kolejki program domyślnie czeka na dostęp do kolejki dopóki nie zwolni się miejsce. A przy pobieraniu z kolejki czeka aż pojawi się jakikolwiek element. Ustaw wejścia timeout na 0 i sprawdzaj/reaguj dynamicznie na wyjście timed out?

MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 13 kwie 2017 12:53

Dzięki za odpowiedź.
To by wiele wyjaśniało a wcześniej nie zwróciłem na to uwagi.
W powyższym przykładzie zdarza się, że pętla producenta zwalnia generując opóźnienie nawet do 1000ms
Po wprowadzeniu timeout pojawiają się dziury w danych odebranych.
Załóżmy, że karta generuje dane co 2,5ms to jaki timeout ustawić w enqueue? jakiś zbliżony większy ok 3, czy jakiś większy np 20 wystarczy?
Czy może jakiś ok 2x większy czyli ok 2,5x2 = 5?

Problem rozwiązany
Zostaje jeszcze ewentualnie kwestia pytania dodatkowego
MK_Zuk pisze:Czy jest może jakieś lepsze rozwiązanie na wyciągnięcie więcej niż jednego elementu z kolejki?

Awatar użytkownika
Pitol
Moderator
Posty: 910
Rejestracja: 19 lip 2007 00:00
Wersja środowiska: LabVIEW 2015
Lokalizacja: Kraków
Has thanked: 1 time
Been thanked: 6 times

Re: struktura producent konsument - rozmiar bufora

Post autor: Pitol » 13 kwie 2017 13:35

W przypadku pętli producenta zamiast Timeout powinieneś użyć bloczka Lossy Enqueue Element, który nie będzie czekał na wolną kolejkę, tylko wyrzuci z kolejki element z przodu aby dodać coś nowego do niej.
Użycie Timeout na tradycyjnym bloczku (Enqueue Element) spowoduje, że dany element nie zostanie wrzucony do kolejki. Po prostu bloczek poczeka i jak nie będzie miejsca w kolejce to przejdzie dalej.
Lossy Enqueue Element zagwarantuje Ci miejsce w kolejce.

Co do wyciągania większej ilości elementów z kolejki to możesz zapiąć sam bloczek Dequeue Element w pętle While/For i czytać do oporu.
Problem będzie z analizą tych danych potem bo cała pętla konsumenta się nie wyrobi...
Możesz zrobić wiele pętli konsumenta, które równolegle obsługują Twoją kolejkę.
Wszystko zależy jakie dane przesyłasz i co chcesz z nich zrobić.

EDIT:
Jest jeszcze jedna opcja.
Możesz użyc bloczka Get Queue Status. Zwraca on zawartość całej kolejki w postaci tablicy elementów.
Minus jest taki, że nie ściąga ich z kolejki.

Ale w Twoim przykładzie to może być nawet rozsądne rozwiązanie.
Producent ładuje do kolejki ile wlezie bloczkiem Lossy Enqueue Element a Konsument tylko podgląda (Get Queue Status) co jest w kolejce i analizuje te dane.
Nie musisz nic z kolejki wyciągać, bo Producent załatwia sprawę przesuwania elementów w kolejce.
Jedyne co musisz zadbać, to interpretacja tych danych. Mógłbyś dodać jakiś znacznik/iterator, dzięki któremu wiedziałbyś co to za element w kolejce i czy już go przypadkiem poprzednio nie analizowałeś.
Pozdrawiam Pitol,

Certified LabVIEW Architect, Certified TestStand Developer.

MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

Re: struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 13 kwie 2017 14:15

Dzięki za bardzo cenne wskazówki.
Wygląda na to, że będę musiał poważnie zmodernizować kod.
Muszę użyć Lossy Enqueue Element.
Co do wyciągania z kolejki to chyba w moim przypadku najlepszym będzie zapętlenie Dequeue element i sklejanie wektorów w waveformach.
Pierwszym elementem przetwarzania w pętli konsumenta jest sklejanie okien, żeby zapełnić bufor więc jak dostanę wektor waveformów
to mogę je posklejać i dorzucić na koniec bufora.
Pitol pisze:Możesz zrobić wiele pętli konsumenta, które równolegle obsługują Twoją kolejkę.
Wszystko zależy jakie dane przesyłasz i co chcesz z nich zrobić.
To w kolejkach da się zrobić wielu konsumentów dla jednego producenta?
Myślałem, że konsument może być tylko jeden. Jak wtedy wykryć, który konsument ma odbierać element z kolejki?
Wtedy automatycznie tworzy się wyścig... chyba, że zastosuję jakiś dodatkowy "zewnętrzny" mechanizm przełączania konsumentów.

Awatar użytkownika
Pitol
Moderator
Posty: 910
Rejestracja: 19 lip 2007 00:00
Wersja środowiska: LabVIEW 2015
Lokalizacja: Kraków
Has thanked: 1 time
Been thanked: 6 times

Re: struktura producent konsument - rozmiar bufora

Post autor: Pitol » 13 kwie 2017 14:29

W kwestii szybkiego wyciągania z kolejki to wiele zależy od tego co robisz.
Jeśli te dane są ładowane bardzo szybko, ale np. raz na jakiś czas to można zrobić to zapętleniem odczytu z kolejki i późniejszą analizą całej paczki.
Jeśli dane nadajesz non stop z dużą częstotliwością to już nie będzie tak różowo, bo nie starczy Ci czasu na analizę (chyba, że zrobisz wielu konsumentów).

A co do wielu konsumentów to masz tutaj bardzo uproszczony przykład jak to może zadziałać.
Ma to wiele plusów jak i minusów. Jakbyś chciał to zastosować to najpierw trzeba by przemyśleć czy w Twoim przypadku ma to sens.
Queue.PNG
Pozdrawiam Pitol,

Certified LabVIEW Architect, Certified TestStand Developer.

MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

Re: struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 15 kwie 2017 16:53

Dzięki za odpowiedź.
W teorii jest ok ale tak prostą strukturę raczej ciężko zastosować
w praktycznym rozwiązaniu, gdzie karta DAQ dostarcza dane w pętli producenta
i czas opóźnienia zmienia się w pewnych granicach.

Właśnie testuję rozwiązanie z wcześniejszych postów.

Pozdrawiam
Zuk

Awatar użytkownika
Pitol
Moderator
Posty: 910
Rejestracja: 19 lip 2007 00:00
Wersja środowiska: LabVIEW 2015
Lokalizacja: Kraków
Has thanked: 1 time
Been thanked: 6 times

struktura producent konsument - rozmiar bufora

Post autor: Pitol » 18 kwie 2017 08:41

No to w takim razie zostaje odbieranie danych ze stratami.
Jeśli te straty są przez Ciebie akceptowalne to nie widzę przeszkód.
Pozdrawiam Pitol,

Certified LabVIEW Architect, Certified TestStand Developer.

MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 18 maja 2017 14:56

Dziękuję za pomoc.
Rozwiązaniem okazało się buforowanie danych w pętli producenta i wysyłanie co kilka iteracji
(wyszło co 15) i działa bez strat.
Próba wielokrotnego odbierania danych i czyszczenia kolejki w jednej iteracji konsumenta zawiodła,
jest to również dobre rozwiązanie jednak problem powodowała zmienna funkcjonalna
przekazująca parametry konfiguracyjne do przetwarzania z innej pętli.

Pozdrawiam
Zuk

Awatar użytkownika
Pitol
Moderator
Posty: 910
Rejestracja: 19 lip 2007 00:00
Wersja środowiska: LabVIEW 2015
Lokalizacja: Kraków
Has thanked: 1 time
Been thanked: 6 times

struktura producent konsument - rozmiar bufora

Post autor: Pitol » 18 maja 2017 16:08

Czyli rozumiem, że wysyłasz dane w paczkach a nie pojedynczo?
I pętla konsumenta sobie radzi na czas z analizą większej paczki niż pojedynczych elementów?
Pozdrawiam Pitol,

Certified LabVIEW Architect, Certified TestStand Developer.

MK_Zuk
Posty: 80
Rejestracja: 01 gru 2009 11:53
Wersja środowiska: LabVIEW 2014
Has thanked: 1 time
Been thanked: 1 time

Re: struktura producent konsument - rozmiar bufora

Post autor: MK_Zuk » 22 sie 2017 22:26

Generalnie pętla producenta zapisuje dane w waveformie,
jedna iteracja dodaje 26 próbek do waveforma,
co 15 iteracji wysyła waveforma zawierającego 390 próbek...

Pozdrawiam
Zuk

ODPOWIEDZ