B>Прокомментируйте кто-нибудь, плз. А то не силён в много поточности.
Добавлю еще то, что такой код -- обычно реакция на факт того, что wait() и notify() бросают (по какой-то непонятной причине!) IllegalMonitorStateException, если они не находятся в synchronized блоке. Brute force решение -- это как раз обернуть вызовы этих методов в synchronized блок, что б JVM успокоилась. На самом деле, в synchronized блоке, кроме этих вызовов, должен быть еще и код, который обращается к объектам, к которым обращается код и из других потоков. В противном случае, мы рискуем получить общие объекты в неконсистентном состоянии из-за несинхронизированного доступа.
В приведенном случае
synchronized (this) { // этот this == commandProcessor из верхнего куска кода.
wait();
}
while (inputQueue.size() > 0) { // {1}
Command c = inputQueue.remove(0); // {2}
handleCommand(c);
Thread.yield();
}
несинхронизирован доступ к inputQueue. Несмотря на то, что в точке {1} проверяется размер коллекции, мы уже не можем с уверенностью вызывать в точке {2} remove(0) потому, что какой-нибудь другой поток мог эту коллекцию изменить. И то, что у этой коллекции методы сами синхронизированы (Collections.synchronized...) никак не спасает. Мы, конечно, можем посчитать, что вызов remove(0) совершенно безопасен поскольку другие потоки не удаляют элементы, а лишь добавляют их -- но это предположение базируется на логике кода, который физически удален от данного, а значит, это предположение легко может стать неверным в процессе эволюции программы.
Далее... wait() всегда должен быть в цикле, даже не столько из-за spurious wakeups, сколько из-за читабельности.
Глядя на
synchronized(this) {
wait();
// . . .
}
невозможно сказать какое событие мы в данном месте ждем без анализа остального кода. А глядя на такой
Дело в том, что notify() пробуждает первый попавшийся поток, а их может на объекте спать много. Также, по крайней мере в теории, есть случаи, когда поток может проснуться "сам по себе".
В приведённом мной коде наш поток точно проснётся и только тогда, когда хотим мы.
Здравствуйте, xBlackCat, Вы писали:
BC>Здравствуйте, Blazkowicz, Вы писали:
BC>От сервера всегда приходит один ключ с типом Writable, в результате чего этот цикл крутится впустую. Попытался динамически менять подписку на ключи — ключи начали теряться и происходил затык. Ещё один поток на отсылку не целесообразно вводить, ИМХО. BC>Подскажите, в какую сторону теперь копать для решения проблемы.
Похоже на то, что использование NIO в данном случае не совсем оправдано, так как у тебя есть одно долго-живущее соединение, которое всегда готово к чтению/записи данных а вот сами то данные послупают относительно редко. То естьвесьтвой механизм работает в холостую.
Возможно стоит откатить программу на использование обычного блокируемого IO с двумя потоками — один на чтение второй на запись — надкладные расходы небольшие за асинхронность.
Как вариант, если уж так принципиально NIO, попробуй поиграться с регистрированием socketChannel в селекторе. То есть при пустой исходящей очереди ты подписываешься у селектора на OP_READ. При появлении элементов в очереди — устанавливаешь у SelectionKey interestOps на OP_READ | OP_WRITE (вероятно придется сделать wakeup селектору). Когда очередь становится пустой — вяртаешь OP_READ онли.
Здравствуйте, xBlackCat, Вы писали:
BC>Доброго времени суток.
BC>Пишу многопоточное приложение и очень напрягает загрузка процессора под 100% во время его работы. BC>Суть приложения заключается в следующем: создать несколько подключений к серверу и посылать/принимать комманды от оного. Подключение открывается отдельным сокетом и его(подключение) обслуживают два потока — один для чтения/записи, второй для исполнения накопленных комманд от сервера. Код примерно следующий:
Многопоточный код должен работать и без Thread.yield() если многопоточность вытесняющая (а она именно такая на большинстве современных платформ).
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, 245_Monah, Вы писали:
B>Что-то мы не в те дебри углубились. Проблемы в кодеке-то к теме вопроса не относятся. Те методы что ты привел они просто много и часто вызываются наверное. B>Мне каежтся что надо попробовать покрутить размер буфера чтения. Так чтобы поток некоторое время ждал поступающей информации. Давая тем самым возможность процессору занятся другими задачами. Но при этом будефер не должен быть на столько большим что кодирование будет долгим. То есть нужно какой-то баланс найти. Вообще как мне кажется кодирование часто довольно трудоёмкая задача и не всегда её можно решить с малой нагрузкой на процессор.
Если интересны исходы Кодера могу выслать, так сказать в благодарность
Пишу многопоточное приложение и очень напрягает загрузка процессора под 100% во время его работы.
Суть приложения заключается в следующем: создать несколько подключений к серверу и посылать/принимать комманды от оного. Подключение открывается отдельным сокетом и его(подключение) обслуживают два потока — один для чтения/записи, второй для исполнения накопленных комманд от сервера. Код примерно следующий:
Поток для обслуживания сокета:
public void run() {
try {
while (socketListenerThread == Thread.currentThread()) {
if (selector.select() > 0)
for (Iterator<SelectionKey> i = selector.selectedKeys().iterator();
socketListenerThread == Thread.currentThread() && i.hasNext();) {
SelectionKey key = i.next();
i.remove();
if (key.isValid()) {
if (key.isConnectable()) {
SocketChannel sc = (SocketChannel) key.channel();
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
sc.finishConnect();
} else if (key.isReadable()) {
readPacket(); // Прочитать пакет и сохранить в очереди командsynchronized (commandProcessor) {
commandProcessor.notify();
}
} else if (key.isWritable()) {
writePackets(); // Взять из очереди комманду и отослать на сервер
}
}
}
Thread.yield();
}
} catch (IOException e) {
}
... // Всё почистить за собой
}
Поток, обрабатывающий очередь команд:
public void run() {
try {
while (commandProcessorThread == Thread.currentThread()) {
synchronized (this) { // этот this == commandProcessor из верхнего куска кода.
wait();
}
while (inputQueue.size() > 0) {
Command c = inputQueue.remove(0);
handleCommand(c);
Thread.yield();
}
}
} catch (InterruptedException e) {
} finally {
socketListenerThread = null;
if (selector != null)
selector.wakeup();
}
}
Профайлер говорит, что всё время забирают выделленные жирным строки кода. В связи с этим такие вопросы: Как это лечится, и, в принципе, правильно ли организована работа потоков?
извеняюсь что не разобрался в Вашем коде но могу точно сказать что, когда я писал много поточное приложение такого же типа у меня тоже проц грузился так. Причина — цикл функции run очень быстро крутился без задржек, я долго мучился прежде чем нашел из за чего.
Здравствуйте, xBlackCat, Вы писали:
BC>Пишу многопоточное приложение и очень напрягает загрузка процессора под 100% во время его работы. BC>Суть приложения заключается в следующем: создать несколько подключений к серверу и посылать/принимать комманды от оного. Подключение открывается отдельным сокетом и его(подключение) обслуживают два потока — один для чтения/записи, второй для исполнения накопленных комманд от сервера. Код примерно следующий:
BC>Поток, обрабатывающий очередь команд: BC>
BC> public void run() {
BC> try {
BC> while (commandProcessorThread == Thread.currentThread()) {
BC> synchronized (this) { // этот this == commandProcessor из верхнего куска кода.
BC> wait();
BC> }
BC> while (inputQueue.size() > 0) {
BC> Command c = inputQueue.remove(0);
BC> handleCommand(c);
BC> Thread.yield();
BC> }
BC> }
BC> } catch (InterruptedException e) {
BC> } finally {
BC> socketListenerThread = null;
BC> if (selector != null)
BC> selector.wakeup();
BC> }
BC> }
BC>
BC>Профайлер говорит, что всё время забирают выделленные жирным строки кода.
Во время Thread.yield() поток отдаёт управление другим потокам, если им есть, что делать, а сам ждёт. Пока он ждёт, ресурсы он не тратит, но время идёт.
Здравствуйте, Sahivi, Вы писали:
S>извеняюсь что не разобрался в Вашем коде но могу точно сказать что, когда я писал много поточное приложение такого же типа у меня тоже проц грузился так. Причина — цикл функции run очень быстро крутился без задржек, я долго мучился прежде чем нашел из за чего.
А можно поподробнее — какой из двух циклов Вы имеете ввиду? И как исправили?
Здравствуйте, xBlackCat, Вы писали:
BC>Здравствуйте, Lucker, Вы писали:
L>>Здравствуйте, xBlackCat, Вы писали:
BC>>>Поток, обрабатывающий очередь команд: L>>
BC>И теперь нельзя будет выйти из потока не прервав его — выделенный цикл будет постоянно работать в конце работы при очереди нулевой длины.
в том то все и дело что выделенный цикл заставит поток приостанавливаться и давать возможность другим потокам занять процесорное время, пока не будет вызван нотифай и в очереди не окажется объекта.
Здравствуйте, xBlackCat, Вы писали:
BC>Чем это поможет?
BC>И теперь нельзя будет выйти из потока не прервав его — выделенный цикл будет постоянно работать в конце работы при очереди нулевой длины.
кстати, если твой поток объяевлен как демон — jvm сама убъет его при завершении работы системы (если не останется ни одного не демон потока)
Здравствуйте, xBlackCat, Вы писали:
BC>Чем это поможет?
BC>И теперь нельзя будет выйти из потока не прервав его — выделенный цикл будет постоянно работать в конце работы при очереди нулевой длины.
Весь код за тебя писать никто не будет. Lucker тебе пытается сказать что надо пересмотреть свой код и выкинуть исполнение пустых циклов. Вот скажи зачем они? Зачем каждый раз "что-то" проверять. Если можно остановить действие потка до тех пор пока "это" не поризойдет?
Здравствуйте, Donz, Вы писали:
D>Во время Thread.yield() поток отдаёт управление другим потокам, если им есть, что делать, а сам ждёт. Пока он ждёт, ресурсы он не тратит, но время идёт.
Угу, обычно в ОС занято совсем не много ресурсов, вот она и отдаёт все оставшиеся этим пустым циклам.
Здравствуйте, Lucker, Вы писали:
L>Здравствуйте, xBlackCat, Вы писали:
BC>>Здравствуйте, Lucker, Вы писали:
L>>>Здравствуйте, xBlackCat, Вы писали:
BC>>>>Поток, обрабатывающий очередь команд: L>>>
L>в том то все и дело что выделенный цикл заставит поток приостанавливаться и давать возможность другим потокам занять процесорное время, пока не будет вызван нотифай и в очереди не окажется объекта.
Но разве это не то же самое, что и было? Размер очереди проверяется и так и этак. Только в моём коде проверка была вне куска synchronized.
Вопрос был ещё в другом. Чтобы не поломать логику, надо условие изменить (поправлено в коде).
Здравствуйте, xBlackCat, Вы писали:
L>>в том то все и дело что выделенный цикл заставит поток приостанавливаться и давать возможность другим потокам занять процесорное время, пока не будет вызван нотифай и в очереди не окажется объекта. BC>Но разве это не то же самое, что и было? Размер очереди проверяется и так и этак. Только в моём коде проверка была вне куска synchronized.
Ну так доступ к очереди не синхронизирован и поэтому поведение кода вообще трудно предсказать.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, xBlackCat, Вы писали:
B>Весь код за тебя писать никто не будет. Lucker тебе пытается сказать что надо пересмотреть свой код и выкинуть исполнение пустых циклов. Вот скажи зачем они? Зачем каждый раз "что-то" проверять. Если можно остановить действие потка до тех пор пока "это" не поризойдет?
Вот я и хочу понять, чем этот код:
while (true) {
synchronized(this) {
wait();
}
while (size > 0) {
size--;
}
}
отличается от
while (true) {
synchronized(this) {
while(size == 0)
wait();
}
while (size > 0) {
size--;
}
}
Здравствуйте, xBlackCat, Вы писали:
B>>Весь код за тебя писать никто не будет. Lucker тебе пытается сказать что надо пересмотреть свой код и выкинуть исполнение пустых циклов. Вот скажи зачем они? Зачем каждый раз "что-то" проверять. Если можно остановить действие потка до тех пор пока "это" не поризойдет?
BC>Вот я и хочу понять, чем этот код: BC>Можете подробнее объяснить?
Самому интересно. И все же. Когда у тебя перестанут работать пустые циклы тогда и загрузка на 100% исчезнет. Скажешь что у тебя их нет?
Здравствуйте, Blazkowicz, Вы писали:
B>Самому интересно. И все же. Когда у тебя перестанут работать пустые циклы тогда и загрузка на 100% исчезнет. Скажешь что у тебя их нет?
Здравствуйте, xBlackCat, Вы писали:
B>>Самому интересно. И все же. Когда у тебя перестанут работать пустые циклы тогда и загрузка на 100% исчезнет. Скажешь что у тебя их нет?
BC>Не знаю. Буду искать... BC>А это BC>
Я не совем точно выразился. Наверное более подходящее определение "бесполезный цикл". То есть тот цикл который выполняется во время простоя. Если у тебя система в режиме ожидания ничего не делает, то соответственно никакой код выполнятся не должен. А когда система крутит циклы в своё удовольствие даже во время ожидания данных, тогда и загрузка процессора соответствующая.
D>Дело в том, что notify() пробуждает первый попавшийся поток, а их может на объекте спать много.
Это понятно, но я подозреваю что автор знает что у него один поток и только его лочит на этом объекте.
D>Также, по крайней мере в теории, есть случаи, когда поток может проснуться "сам по себе".
Подробности этих случаев известны?
D>В приведённом мной коде наш поток точно проснётся и только тогда, когда хотим мы.
Ну, да. Но для одного потока и одного процессора команд, вроде как и исходный код в этом плане ничего. Или я чего-то не вижу?
Но в принципе идею понял. Если вдруг нужна будет многопоточная обработка, то много чего сразу перестанет работать.
Здравствуйте, Blazkowicz, Вы писали:
B>Это понятно, но я подозреваю что автор знает что у него один поток и только его лочит на этом объекте.
Лучше сразу выработать автоматизм в таких случаях. Появится второй поток и может много времени уйти ни на что. Тем более, что кроме "пользовательских" есть ведь ещё и другие потоки, мало ли, может кто из них вызовет notify на этом объекте.
D>>Также, по крайней мере в теории, есть случаи, когда поток может проснуться "сам по себе". B>Подробности этих случаев известны?
Не помню где, но читал каким образом может поток проснуться. Одни из вариантов было именно "сам по себе", мол редко, но случается. Найти не могу, может даже где-то здесь на РСДН инфа проскакивала. Если найду — ссылку кину.
B>Но в принципе идею понял. Если вдруг нужна будет многопоточная обработка, то много чего сразу перестанет работать.
Именно, лучше сразу сделать так как надо, это собственно в учебниках описывается. Тем более, надо то добавить одно поле и цикл, не такая уж большая плата за отсутствие потенциальных ошибок такого рода.
Кстати, вот сделали wait() на объекте. Потом этот объект где-то обратили в null, а потом разбудить забыли, что будет? Объект не будет уничтожен, пока на нём спит поток?
Здравствуйте, Blazkowicz, Вы писали:
B>Я не совем точно выразился. Наверное более подходящее определение "бесполезный цикл". То есть тот цикл который выполняется во время простоя. Если у тебя система в режиме ожидания ничего не делает, то соответственно никакой код выполнятся не должен. А когда система крутит циклы в своё удовольствие даже во время ожидания данных, тогда и загрузка процессора соответствующая.
Проблемный цикл найден! Собственно — вот он:
while (socketListenerThread == Thread.currentThread()) {
int keyNumber = selector.select();
if (keyNumber > 0) {
for (Iterator<SelectionKey> i = selector.selectedKeys().iterator();
socketListenerThread == Thread.currentThread() && i.hasNext();) {
SelectionKey key = i.next();
i.remove();
if (key.isValid()) {
if (key.isConnectable()) {
socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
socketChannel.finishConnect();
} else if (key.isReadable()) {
clientLogger.debug("--> Readable key");
readPacket();
} else if (key.isWritable()) {
clientLogger.debug("--> Writable key");
writePackets();
}
}
}
}
}
От сервера всегда приходит один ключ с типом Writable, в результате чего этот цикл крутится впустую. Попытался динамически менять подписку на ключи — ключи начали теряться и происходил затык. Ещё один поток на отсылку не целесообразно вводить, ИМХО.
Подскажите, в какую сторону теперь копать для решения проблемы.
Здравствуйте, Donz, Вы писали:
D>>>Также, по крайней мере в теории, есть случаи, когда поток может проснуться "сам по себе". B>>Подробности этих случаев известны? D>Не помню где, но читал каким образом может поток проснуться. Одни из вариантов было именно "сам по себе", мол редко, но случается. Найти не могу, может даже где-то здесь на РСДН инфа проскакивала. Если найду — ссылку кину.
Здравствуйте, Donz, Вы писали:
D>>>>Также, по крайней мере в теории, есть случаи, когда поток может проснуться "сам по себе". B>>>Подробности этих случаев известны? D>>Не помню где, но читал каким образом может поток проснуться. Одни из вариантов было именно "сам по себе", мол редко, но случается. Найти не могу, может даже где-то здесь на РСДН инфа проскакивала. Если найду — ссылку кину.
D>Skipy с juga.ru нашёл корни, скорее всего в моём источнике упоминался именно этот случай: D>http://gcc.gnu.org/ml/java-prs/1999-q3/msg00072.html D>Может и ещё что-нибудь в этом духе встречается.
Решил продолжить тему, а как быть если у меня крутится RTP протокольчик где постоянно приходят пакеты с данными и остановка потока приравнивает к потере данных, если кто сталкивался с этим с удовольствием выслушаю??? С уважением Гришков И.О.
Здравствуйте, 245_Monah, Вы писали:
_M>Решил продолжить тему, а как быть если у меня крутится RTP протокольчик где постоянно приходят пакеты с данными и остановка потока приравнивает к потере данных, если кто сталкивался с этим с удовольствием выслушаю??? С уважением Гришков И.О.
Объясни куда это данные теряются? А то не очень понятно. Как по мне это равносильно тому что данные так же теряются если не вычитывать их не достаточно быстро?
Здравствуйте, Blazkowicz, Вы писали:
B>Объясни куда это данные теряются? А то не очень понятно. Как по мне это равносильно тому что данные так же теряются если не вычитывать их не достаточно быстро?
Вобщем принцип следующий, значить есть у меня кодер G729A енто вот это обращение "g729a.encode(g729a.handle, buffer, 0, buffer1, 0)", значить боролся я боролся что бы сбить нагрузку на проц и че та нифига неполучилось, кроме этого больше потоков не запущенно, этот запускается один раз, могу привести код самого Кодера G729A, еще прикол, значит пытаюсь весь код вставить в одну линейку в кодере что бы избежать многочисленных обращений к методам других классов, вобщем сократить количество переходов, но если я пытаюсь вставить метод конкретно в тело, то нагрузка увеличивается вдвое, пробывал отладочные печати, пустых цыклов ненашел, в чем бок для меня осталось загадкой С уважением Гришков И.О.
Здравствуйте, 245_Monah, Вы писали:
_M>привожу пример:
Ты жу не обижайся, но код форамтировать надо чтобы хоть кто-то удосужился прочитать. Так уж и быть подправлю твой пост.
_M>Вобщем принцип следующий, значить есть у меня кодер G729A енто вот это обращение "g729a.encode(g729a.handle, buffer, 0, buffer1, 0)", значить боролся я боролся что бы сбить нагрузку на проц и че та нифига неполучилось, кроме этого больше потоков не запущенно, этот запускается один раз, могу привести код самого Кодера G729A, еще прикол, значит пытаюсь весь код вставить в одну линейку в кодере что бы избежать многочисленных обращений к методам других классов, вобщем сократить количество переходов, но если я пытаюсь вставить метод конкретно в тело, то нагрузка увеличивается вдвое, пробывал отладочные печати, пустых цыклов ненашел, в чем бок для меня осталось загадкой _M> С уважением Гришков И.О.
А профайлер пробовал? Ты легко найдешь кто дает бОльшую нагрузку? inputAudioStream.read(buffer);
Может имеет смысл поигратся с размером буфера? Если к примеру inputAudioStream.read(buffer); вычитывает не очень много данных, то цикл выполняется очень часто. Если найти способ увеличть время выполнение цикла, пока буфер определенного размера не будет заполнен, то и цикл не будет выполнять а поток будет просто ждать пока прийдет достаточно данных. inputAudioStream хотя бы обернут в BufferedInputStream?
Здравствуйте, Blazkowicz, Вы писали:
B>Ты жу не обижайся, но код форамтировать надо чтобы хоть кто-то удосужился прочитать. Так уж и быть подправлю твой пост.
B>А профайлер пробовал? Ты легко найдешь кто дает бОльшую нагрузку? inputAudioStream.read(buffer); B>Может имеет смысл поигратся с размером буфера? Если к примеру inputAudioStream.read(buffer); вычитывает не очень много данных, то цикл выполняется очень часто. Если найти способ увеличть время выполнение цикла, пока буфер определенного размера не будет заполнен, то и цикл не будет выполнять а поток будет просто ждать пока прийдет достаточно данных. inputAudioStream хотя бы обернут в BufferedInputStream?
Неа, необернут, попробую этот вариант, просто уже крышу рвет от этого Кодера, просто я не думаю что следующий кусок кода "g729.encode(buffer, 0, buffer1, 0)" выполняется шустро, привожу пример пример одного из его методов "Квантование линейного спектра или Quantazing LSP":
А за форматирование прошу прощение, был напуган, с буфером попробую, но блин боюсь мало успеха будет, просто реально народ, уже бошка невыдерживает четвертый месяц немогу сбить нагрузку на проц и именно с Кодером, Декодер все чики пуки, а вот кодер какая то жопа, уже начал линейную структуру кода создавать, что бы Java меньше с переходами парилась
Здравствуйте, 245_Monah, Вы писали:
_M>Неа, необернут, попробую этот вариант, просто уже крышу рвет от этого Кодера, просто я не думаю что следующий кусок кода "g729.encode(buffer, 0, buffer1, 0)" выполняется шустро, привожу пример пример одного из его методов "Квантование линейного спектра или Quantazing LSP":
Все равно не понятно какого размера данные приезжают в буфер и как часто выполняется тело цикла.
_M>А за форматирование прошу прощение, был напуган, с буфером попробую, но блин боюсь мало успеха будет, просто реально народ, уже бошка невыдерживает четвертый месяц немогу сбить нагрузку на проц и именно с Кодером, Декодер все чики пуки, а вот кодер какая то жопа, уже начал линейную структуру кода создавать, что бы Java меньше с переходами парилась
Здравствуйте, Blazkowicz, Вы писали:
B>Все равно не понятно какого размера данные приезжают в буфер и как часто выполняется тело цикла.
B>Ключевое слово Profiler.
Размер буффера 160 байт, просто если я ремлю вызов кодера тогда бесконечный цикл, ну вернее пока приходят данные со звуковой карты, крутится без проблем и нагрузка на проц 04%, кароче понт ваабще, а тока подкидываю кодер, все машина умирает, а с профалером я все таки попробую покопать, наверное уже заффтра скажу результаты, спасибочки что отозвался
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, 245_Monah, Вы писали:
_M>>Неа, необернут, попробую этот вариант, просто уже крышу рвет от этого Кодера, просто я не думаю что следующий кусок кода "g729.encode(buffer, 0, buffer1, 0)" выполняется шустро, привожу пример пример одного из его методов "Квантование линейного спектра или Quantazing LSP":
B>Все равно не понятно какого размера данные приезжают в буфер и как часто выполняется тело цикла.
_M>>А за форматирование прошу прощение, был напуган, с буфером попробую, но блин боюсь мало успеха будет, просто реально народ, уже бошка невыдерживает четвертый месяц немогу сбить нагрузку на проц и именно с Кодером, Декодер все чики пуки, а вот кодер какая то жопа, уже начал линейную структуру кода создавать, что бы Java меньше с переходами парилась
B>Ключевое слово Profiler.
А подскажи пожалуйста, есть ли возможность в Профайлере, посмотреть конкретно что за цикл или что за опирации в цикле загружают процессор, потому что какие методы загружают я вижу но что конкретно в них загружет немогу понять???
Здравствуйте, 245_Monah, Вы писали:
_M>А подскажи пожалуйста, есть ли возможность в Профайлере, посмотреть конкретно что за цикл или что за опирации в цикле загружают процессор, потому что какие методы загружают я вижу но что конкретно в них загружет немогу понять???
Нам предоставляется уникальная возможность угадать что же за профайлер ты используешь? В OptimzeIt точно есть. Напротив каждого метода пишется сколько ms ушло на его выполнение. Что там с другими профайлерами, не скажу, не знаю. Но подобная фича должна быть у всех.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, 245_Monah, Вы писали:
B>Нам предоставляется уникальная возможность угадать что же за профайлер ты используешь? В OptimzeIt точно есть. Напротив каждого метода пишется сколько ms ушло на его выполнение. Что там с другими профайлерами, не скажу, не знаю. Но подобная фича должна быть у всех.
Это из серии, ВНИМАНИЕ знатоки, вы играете со мной, угадайте какой у меня профайлер , блин я бы тоже посмеялся, да только непалучается, пользуюсь я баянистым JProfiler ej-Technologies, он тоже мне пишет сколько времени ушло на выполнение метода и т.д. и т.п., так вот, кодер как известно это куча арифметики и соответственно куча циклов, так вот, есть у меня метод, который JProfiler говорит что он нагружает пиз... ну типа времени занимает дофига, а да еще забыл, JProfiler считает общее время с момента старта проги, вот, показываю пример этого метода:
public long L_mac(long L_var3, int var1, long var2) {
long L_var_out;
long L_produit;
L_produit = L_mult(var1,var2);
L_var_out = L_add(L_var3,L_produit);
return(L_var_out);
}
а вот эти два метода которые он использует, ну очень навороченные методы
public long L_mult(int var1, long var2) {
long L_var_out;
L_var_out = var1 * var2;
if (L_var_out != 0x40000000) {
L_var_out *= 2;
} else {
L_var_out = MAX_64;
}
return(L_var_out);
}
public long L_add(long L_var1, long L_var2) {
long L_var_out;
L_var_out = L_var1 + L_var2;
if (((L_var1 ^ L_var2) & MIN_64) == 0) {
if (((L_var_out ^ L_var1) & MIN_64)>0) {
L_var_out = (L_var1 < 0) ? MIN_64 : MAX_64;
Overflow = true;
}
}
return(L_var_out);
}
Вобщем я в шоке, еще одна вещь, ставлю отладочные печати по времени, на сам метод Encode в нашем созданном потоке, вот что получается(это фрагментик, что бы лишних вопросов не возникало):
1173793056812
************************
1173793056828
1173793056828
************************
1173793056828
1173793056843
************************
1173793056843
1173793056843
************************
1173793056859
1173793056859
************************
1173793056875
1173793056875
************************
1173793056890
Здесь:
<Время до вызова метода Encode>
************************
<Время после вызова Encode>
Что-то мы не в те дебри углубились. Проблемы в кодеке-то к теме вопроса не относятся. Те методы что ты привел они просто много и часто вызываются наверное.
Мне каежтся что надо попробовать покрутить размер буфера чтения. Так чтобы поток некоторое время ждал поступающей информации. Давая тем самым возможность процессору занятся другими задачами. Но при этом будефер не должен быть на столько большим что кодирование будет долгим. То есть нужно какой-то баланс найти. Вообще как мне кажется кодирование часто довольно трудоёмкая задача и не всегда её можно решить с малой нагрузкой на процессор.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, 245_Monah, Вы писали:
B>Что-то мы не в те дебри углубились. Проблемы в кодеке-то к теме вопроса не относятся. Те методы что ты привел они просто много и часто вызываются наверное. B>Мне каежтся что надо попробовать покрутить размер буфера чтения. Так чтобы поток некоторое время ждал поступающей информации. Давая тем самым возможность процессору занятся другими задачами. Но при этом будефер не должен быть на столько большим что кодирование будет долгим. То есть нужно какой-то баланс найти. Вообще как мне кажется кодирование часто довольно трудоёмкая задача и не всегда её можно решить с малой нагрузкой на процессор.
Лана, все равно огромное спасибо, добавлю только что в линейном потоке без буферизации C код этого же кодека, загружает на 15-20 процентов проц, в этом то и вся проблема, остается искать в Java кодере проблему