Piszę kod, który odbiera surowe pakiety ethernetowe (bez TCP/UDP) co 1ms z serwera. W przypadku każdego odebranego pakietu moja aplikacja musi odpowiedzieć 14 nieprzetworzonymi pakietami. Jeśli serwer nie odbierze 14 pakietów, zanim wyśle pakiet zaplanowany na każde 1 ms, serwer zgłosi alarm, a aplikacja musi się zepsuć. Komunikacja między serwerem a klientem to połączenie jeden-jeden.Odbieranie pakietów gniazd RAW z dokładnością do mikrosekund
Serwer to sprzęt (FPGA), który generuje pakiety z dokładnością do 1ms. Aplikacja kliencka działa na maszynie Linux (RHEL/Centos 7) z 10G SolarFlare NIC.
Moja pierwsza wersja kodu jest jak ten
while(1)
{
while(1)
{
numbytes = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
if(numbytes > 0)
{
//Some more lines here, to read packet number
break;
}
}
for (i=0;i<14;i++)
{
if (sendto(sockfd,(void *)(sym) , sizeof(sym), 0, NULL, NULL) < 0)
perror("Send failed\n");
}
}
zmierzyć czasu odbioru poprzez znaczniki czasu (używając clock_gettime
) przed wywołaniem recvfrom
i jeden po niej drukować różnice czasowe tych znaczników czasu i wydrukować je, gdy różnica czasu przekracza dopuszczalny zakres 900-1100 nas.
Problem jestem stoi to, że pakiet otrzymać czas fluctuating.Something tak (odciski są w mikrosekund)
Decode Time : 1234
Decode Time : 762
Decode Time : 1593
Decode Time : 406
Decode Time : 1703
Decode Time : 257
Decode Time : 1493
Decode Time : 514
and so on..
a czasami czasy dekodowania przekraczać 2000us i stosowania pęknie.
W tej sytuacji aplikacja może zostać przerwana w dowolnym miejscu w zakresie od 2 sekund do kilku minut.
Opcje wypróbowane przeze mnie do tej pory.
- Ustawianie powinowactwa do określonego izolowanego rdzenia.
- ustawień priorytetów szeregowania maksymalnie buforem gniazda
SCHED_FIFO
- Zwiększenie wielkości
- sieciowa Ustawienie przerwania powinowactwo do samego rdzenia, który procesów nakładania
- Spinning na
recvfrom
pomocąpoll(),select()
połączenia.
Wszystkie te opcje dają znaczną poprawę w stosunku do początkowej wersji kodu. Teraz aplikacja działała przez ~ 1-2 godziny. Ale to wciąż nie wystarcza.
Kilka obserwacji:
- mam aa ogromny zrzut tych odbitek czasu dekodowania, gdy biorę sesji ssh na komputerze z systemem Linux, podczas gdy aplikacja jest uruchomiona (co sprawia, że myślę komunikację sieciową na inny interfejs 1G Ethernet powoduje zakłócenia w interfejsie Ethernet 10G).
- Aplikacja działa lepiej w RHEL (czas pracy około 2-3 godzin) niż Centos (czas pracy około 30 minut - 1,5 godziny)
- Czas pracy jest również różny w przypadku maszyn Linux z różnymi konfiguracjami sprzętowymi z tym samym OS.
Proszę zasugerować, czy istnieją inne metody poprawy czasu działania aplikacji.
Z góry dziękuję.
Oprócz czasu przetwarzania, musisz zrozumieć, że w rzeczywistym świecie sieci znacznie różnią się czasem dostarczania pakietów. Możesz to w pewnym stopniu złagodzić, jeśli jest to wszystko w twojej sieci (nie przechodzi przez Internet), jeśli masz solidne zasady QoS w miejscu i definiujesz kolejki priorytetowe dla tego ruchu. W przeciwnym razie nie próbowałbym nawet próbować używać czegoś z tak bliskim czasem w sieci. –
Proponuję Ci, jeśli możesz, spróbować użyć skompilowanego jądra Linux PREEMPT_RT. – LPs
Byłoby miło wiedzieć, co chcesz osiągnąć, ponieważ, certyfikując, wysyłanie pakietów z tą dokładnością nie jest możliwe przez Ethernet. Sugerowałbym posiadanie kolejnego FPGA do przetworzenia twojego interfejsu danych AND z twoim PC. – Koshinae