|
Real time на Windows XP |
|
|
|
Sep 27 2012, 20:58
|
Группа: Участник
Сообщений: 10
Регистрация: 28-10-11
Пользователь №: 68 007

|
Добрый день! Понимаю всю обсурдность вопроса... но стоит задача - обеспечить передачу UDP пакетов в сеть с жестким интервалом 10мс. Система только виндоуз и ничего кроме виндоуз. (Причины: драйвера, ПО, просто лень разработчиков изучать другие системы) В общем, уговорить перейти на что-то более адекватное у меня не получается. Какие есть варианты? Мультимедия таймер не обеспечивает необходимой точности. http://www.intervalzero.com/ - вроде бы то, что нужно. Но непонятно, сколько времени уйдет на освоение и сколько вообще это будет стоить. Если подключить к COM порту контроллер, который будет каждые 10мс посылать сигнал, и роботать по прерыванию - может это как-то улучшить ситуацию?
|
|
|
|
|
 |
Ответов
(30 - 44)
|
Oct 1 2012, 22:10
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(Slovan @ Oct 1 2012, 14:05)  Колебание 7-13мс. При чем на семерке пакеты идут вокруг 10.0 мс, а на ХР где-то ~75% приходит в 9.8мс и ~25% в 10.8 мс. Не знаю с чем это связано. Могу (с очень большой вероятностью) предположить, что все эти различия связаны: а). с значением временного тика в системе, б). с дискретностью измерения времени не выше этого значения тика + в). того как вы делаете измерения временных интервалов.Обычно такие измерения очень грубые, чтобы по ним смотреть статистику. P.S. попробуйте измерять по значению счётчика процессорных тактов - RDTSC.
|
|
|
|
|
Oct 2 2012, 06:53
|
Группа: Участник
Сообщений: 10
Регистрация: 28-10-11
Пользователь №: 68 007

|
Цитата(Olej @ Oct 2 2012, 02:10)  P.S. попробуйте измерять по значению счётчика процессорных тактов - RDTSC. Именно так и измеряю. Цитата на венде легко выставить приоритет задаче. можно выставить... как же он называется... . TimeCriticalPriority чтоли, ну или выше, чуть ли не реалтаймПриорити. При каком приоритете какие результаты? Какие результаты при самом высоком приоритете? Да все с риалтам приорити естественно.
|
|
|
|
|
Oct 2 2012, 07:02
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(juvf @ Oct 2 2012, 07:16)  на венде легко выставить приоритет задаче. можно выставить... как же он называется... . TimeCriticalPriority чтоли, ну или выше, чуть ли не реалтаймПриорити. "чуть ли не реалтайм"(с) - это высокий класс! Это уже - рождение терминологии! Вообще, сочетания слов "Real time" и "Windows XP" в названии темы - это очень веселит ... я по-началу так и подумал, что это анекдот какой...
|
|
|
|
|
Oct 2 2012, 12:06
|
Группа: Участник
Сообщений: 10
Регистрация: 28-10-11
Пользователь №: 68 007

|
Вот так выглядят тестовые программы: Для передачи: CODE #include <windows.h> #include <tchar.h> #include <stdio.h>
SOCKET sock; struct sockaddr_in to; char tx[] = "testtestestesttestestesttestestesttestestesttestes";
void CALLBACK SendPacket(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) { sendto(sock, tx, 48, 0, (struct sockaddr*)&to, sizeof(struct sockaddr_in)); }
int _tmain(int argc, _TCHAR* argv[]) { SetProcessAffinityMask(GetCurrentProcess(), 0x02); SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
WSADATA wd; WSAStartup(MAKEWORD(2, 2), &wd);
sock = socket(AF_INET, SOCK_DGRAM, 0);
to.sin_family = PF_INET; to.sin_addr.s_addr = INADDR_BROADCAST; to.sin_port = htons(49501); memset(&(to.sin_zero), 0, 8); char on = 1; setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
UINT m_uResolution; TIMECAPS tc; timeGetDevCaps(&tc, sizeof(TIMECAPS)); m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
timeBeginPeriod(m_uResolution);
MMRESULT m_idEvent = timeSetEvent( 10, m_uResolution, SendPacket, NULL, TIME_PERIODIC);
getchar(); return 0; } Для приема: CODE #include <windows.h> #include <tchar.h> #include <stdio.h>
#define TOTAL_PACKETS 10000
double PCFreq = 0.0;
double GetCounter() { LARGE_INTEGER li; QueryPerformanceCounter(&li); return double (li.QuadPart)/PCFreq; }
int _tmain(int argc, _TCHAR* argv[]) {
SetProcessAffinityMask(GetCurrentProcess(), 0x01); SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
LARGE_INTEGER li; QueryPerformanceFrequency(&li); PCFreq = double(li.QuadPart)/1000.0;
WSADATA wd; WSAStartup(MAKEWORD(2, 2), &wd);
SOCKET sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in sa;
sa.sin_family = PF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = htons(49501); memset(&(sa.sin_zero), 0, 8);
bind(sock, (struct sockaddr*)&sa, sizeof(struct sockaddr)); int nbrcvd; char buf[255]; double t0 = 0, t1 = 0, dt = 0; int counter = 0;
unsigned __int32 tbl[100]; memset(tbl, 0, 400);
while (1) {
nbrcvd = recv(sock, buf, sizeof(buf), 0);
if (nbrcvd > 0) {
t1 = GetCounter();
if (t0 == 0) t0 = t1; else { dt = t1-t0; t0 = t1;
//сбор статистики nbrcvd = static_cast<int>((dt+0.1)/0.2); tbl[nbrcvd]++; }
counter++; if (counter == TOTAL_PACKETS) { for (int i = 0; i<100; i++) { if (tbl[i] > 0) fprintf(stdout, " %5.1f ms %5d %5.1f%% \n", (0.2*i), tbl[i], (double) (tbl[i]*100/TOTAL_PACKETS)); }
getchar(); return 0; } } } } Такой результат на семерке, когда обе программы выполняются на одном компе: CODE 8.8 ms 3 0.0% 9.0 ms 6 0.0% 9.2 ms 4 0.0% 9.4 ms 7 0.0% 9.6 ms 9 0.0% 9.8 ms 88 0.0% 10.0 ms 9746 97.0% 10.2 ms 110 1.0% 10.4 ms 11 0.0% 10.6 ms 7 0.0% 10.8 ms 4 0.0% 11.0 ms 1 0.0% 11.2 ms 3 0.0%
Цитата Вообще, сочетания слов "Real time" и "Windows XP" в названии темы - это очень веселит ... я по-началу так и подумал, что это анекдот какой... Самое смешное, что в системе вообще не будет машин с жестким реальным временем. В частности компьютер, которому предназначаются эти пакеты, работает под линуксом, без каких либо реал тайм расширений.
|
|
|
|
|
Oct 2 2012, 12:41
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(Slovan @ Oct 2 2012, 15:06)  Самое смешное, что в системе вообще не будет машин с жестким реальным временем. В частности компьютер, которому предназначаются эти пакеты, работает под линуксом, без каких либо реал тайм расширений. А Linux и расширять ничем не надо: там и так всё, что касается времени - намного серьёзнее. Ну так и вы Linux-ом передавайте?! Кроме того, вся ваша задача к "реалтайм" вообще никакого касательства не имеет - это задача укладывания (более-менее) во временные рамки, задача масштаба времени. Тем более с вовлечением в цепь событий IP-сети, которая по определению не может быть детерминированной. Цитата(Slovan @ Sep 27 2012, 23:58)  стоит задача - обеспечить передачу UDP пакетов в сеть с жестким интервалом 10мс. Система только виндоуз и ничего кроме виндоуз. Хотя ... если задача стоит так, как изначально написано: ПЕРЕДАТЬ в сеть UDP дэйтаграммы с интервалом 10мс., а дальше в той сети ... "хоть трава не расти"...? Может быть, может быть...
|
|
|
|
|
Oct 2 2012, 14:52
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(_Pasha @ Oct 2 2012, 20:37)  Тем более, что можно скомбинировать оба метода и устраивать "ахтунг" по прошествии 5 мс ну или просто спать Код __int64 freq; __int64 t1; __int64 t2; QueryPerformanceFrequency((LARGE_INTEGER *) &freq); QueryPerformanceCounter((LARGE_INTEGER *) &t1); t2 = t1; while (1){ while ((t2 - t1) < 0.01L * freq) QueryPerformanceCounter((LARGE_INTEGER *) &t2); t1 += 0.01L * freq; sendUdpPacket(); Sleep(5); } и не очень хорошо на одном компе такое тестировать, виндовс насколько помню вообще пакет наружу в кабель не вытолкнет если передавать и принимать на адреса одного и того же интерфейса. возможно так было в прошлых версиях и в W7 по другому, но какие-то такие грабли припоминаю.
|
|
|
|
|
Oct 2 2012, 22:05
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(_pv @ Oct 2 2012, 17:52)  и не очень хорошо на одном компе такое тестировать, виндовс насколько помню вообще пакет наружу в кабель не вытолкнет если передавать и принимать на адреса одного и того же интерфейса. возможно так было в прошлых версиях и в W7 по другому, но какие-то такие грабли припоминаю. И не только "не очень хорошо"(с), а категорически нельзя измерять задержки в сетевой клиент-серверной системе (любой, не только в этой задаче) когда клиент и сервер работают на одном хосте, т.е. когда передача идёт на localhost. При этом процесс-клиент и процесс-сервер конкурируют за процессорные кванты и вытесняют друг друга... там начинаются такие чудеса! Это не из области домыслов, а из реальной практики: как только клиент и сервер работают на localhost - временные результаты и зависимости получаются совершенно не те, чем при работе их в реальной LAN. И это не только в Windows (где всё хрен знает как смазано), а в Linux, QNX, Solaris и др. - где всё куда прозрачнее и понятнее.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|