![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| lavan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Задача такая: Написать устойчивое соединение на основе udp пакетов. По сути реализация tcp на прикладном уровне. Программа написанна но имеются серьезные проблемы с производительностью! Я так подозреваю,ято это из-за плохого межпотокового взаимодействия.
Может кто заметит дырку в алгоритме! Имею ack,nack скользящее окно. Использую jxta там есть функ обратного вызова которая вызывается когда приходит пакет(она не реализована ее реализую я).эта функция работает в своем потоке и ее задача просто передать пакет дальше,другому потоку.Передача происходит так:Пришел пакет ждет 1мс на Exchanger если передача не произошла ложит пакет в очередь.Второй поток разбирает пакет,смотрит какому соединению он принадлежит и передает его туда(этот поток имеет максимальный приоритет).Каждое соединение состоит из потока "получатель" и "отправитель" которые имеют доступ к общему буферу(буфер- это класс) в буфере есть три ConcurentHashMap."отправитель" отсылает пакеты,пока он в окне,и ложит их в мап,во второй мап ложит номер пакета и тайм аут а в третий номер пакета и кол-во тайм аутов.по приходу ack "получатель" очищает эти мапы."получатель" работает так: получил пакет,обработал его и уснул по wait пока не пришел очередной пакет.Мне кажется,что потоки не равномерно получают процессорное время.Т.е "отправитель" захватил процессор и шлет,шлет... потом пришла лавина ack-ov и "получатель" захватывает процессор пока не очистит весь буфер,не давая "отправителю" работать.Также есть ощутимая задержка при nack.Т.е принемающая сторона отправляет nack, оправляющая сторона прежде чем получит нак успевает выслать дополнительно 15-25 пакетов.Как это можно исправить? Да,каждый пакет подписывается по алгоритму DSA. |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 2 Всего: 118 |
Я бы попробовал вопрос задать в разделе Алгоритмы - тут больше алгоритмические проблемы.
|
|||
|
||||
| lavan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
там я задал его изначально
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
lavan, очень трудно понять ваше описание задачи. Не скупитесь хотя-бы на запятые. Что такое "ack,nack"? Это ACK-NAK, позитивное и негативное подтверждения приема?
Я бы посмотрел, как логика работает в медленном режиме, когда отправитель шлет пакеты с паузами, чтобы исключить эффекты конкуренции потоков. А потом уже наращивать скорость до естественной.
Тут же еще и сеть участвует. "Равномерности" нет. Это сообщение отредактировал(а) COVD - 17.7.2012, 15:47 |
|||
|
||||
| lavan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Да Ack,Nack-позитивное и негативное подтверждение.
отрабатывает без ошибок в любом режиме.. Проблемы с производительностью возникают когда "отправитель" заполняет буфер(в буфере содержатся отосланные пакеты на которые не приходили ack).Прежде чем получить ack на первый высланный пакет "отправитель" успевает выслать ~ 20-30 пакетов. Когда "отправитель" заполняет буфер он прекращает высылать пакеты и в цикле проверяет тайм ауты пакетов находящихся в буфере.Вот здесь и происходит проблема.Начинают лавиной приходить подтверждения,поток "получатель" захватывает процессор. Получается,что "отправитель" не может выслать ни одного нового пакета,пока не очистится буфер или пока не будет задержки между приходящими подтверждениями(что бывает редко). Т.е я так понимаю проблема свелась к правильной обработке буфера.Но пока решения нет |
|||
|
||||
| COVD |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Можно изменить алгоритм - не "прекращать" заполнять буфер, буфер сделать неограниченным. Контроль таймаутов делать отдельным потоком, "монитором" буфера.
Оптимизация доступа к буферу - дело хорошее. Но не безграничное. Возможно, надо посмотреть в сторону параллельной обработки - разбивать поток данных на менее интенсивные потоки или обслуживать каждым соединением ограниченное количество потребителей. Это сообщение отредактировал(а) COVD - 17.7.2012, 18:15 |
||||
|
|||||
| lavan |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
В таком случае возникнет не нужная загрузка канала.Допустим получатьель отключился,отправитель об этом узнает успев выслать огромное кол-во пакетов в никуда,а если сделать маленький тайм аут то будут слаться не нужные повторения.
не совсем понял.у меня на каждое соединение имеется свой "отправитель" и свой "получатель".общиий поток для всех приходящих пакетов -это поток который определяет какому соединению принадлежит пакет. |
||||
|
|||||
| COVD |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Возможно, если события отключения редки, то это и не так страшно.
У вас приложение работает на одном компьютере. На другом компьютере запустить точно такое же приложение. Если так можно организовать, то легко будет увеличивать производительность добавлением компьютеров. Особенно, когда возможности оптимизации кода уже исчерпаны. |
||||
|
|||||
| lavan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
не,все должно работать на одном компе. для передачи данных по сети,я использую jxta,в ней есть реализация протокола tcp(в принципе эта реализация расширяет java класс ServerSocket),используя эту реализацию,время передачи 10МБ занимает 8сек.а у меня 55сек. Т.е есть простор для оптимизации. |
|||
|
||||
| lavan |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 21.4.2011 Репутация: нет Всего: нет |
Да,и еще,ставлю цифровую подпись на каждый пакет(использую java security и алгоритм DSA) на сколько должно увеличиться время работы программы?
у меня увеличивается на 25%.Кроме того хотелось бы знать,какие временные показатели будут приемлимы(вобщем для работы программы)? Понятное дело,что я не могу реализовать tcp так же как его реализовали програмеры из java(ServerSocket).У меня получается ~40сек на 10МБ из которых 25% времени занимает цифровая подпись. Это сообщение отредактировал(а) lavan - 18.7.2012, 18:05 |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Работа с сетью | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |