Форум » Clipper » Влияние вызова дисковых функций на быстродействие TIME() / SECONDS() » Ответить

Влияние вызова дисковых функций на быстродействие TIME() / SECONDS()

p519446: hi all. Clipper 5.2e + Blinker6. Мне давно известен один эффект, но я не понимаю его природы. Кто-нибудь может объяснить, почему этот вот цикл: #DEFINE I_MAX 20000 // двадцать тысяч FOR I=1 TO I_MAX K:=TIME() // или K:=SECONDS() -- всё равно NEXT -- выполняется на машине P-2400/RAM 512 то 15 секунд, то 20, а то и все 50 сек. При этом процессор грузится практически на 0 (ноль) процентов и, чтобы его раскочегарить, надо держать нажатым Shift или Ctrl или Alt. Замена вызова TIME() на SECONDS() не помогает (имхо, в этом ничего неожиданного нет). Но этот же цикл, добавленный внутри всего лишь одной функцией, обращающейся к... ДИСКУ (!!), выполняется практически мгновенно: #DEFINE I_MAX 20000 FOR I=1 TO I_MAX K:=TIME() FILE('C:\1') NEXT Почтеннейшая публика! Объясните, плз, почему это всё так происходит. ЗЫ-1. Забавно, что если вызывать ф-цию FILE() с аргументом = пустой строке или с некорректным именем (типа "C:\><"), то будет опять всё плохо (т.е. она перестаёт волшебным образом помогать). ЗЫ-2. Тесты проверялись на МИНИМАЛЬНО необходимом наборе библиотек. Никаких приблуд типа SIX,DBFAXF, __WAIT_B, DISIDLE etc. Сборка шла только с BLXCLP52 и CLIPPER.LIB

Ответов - 29, стр: 1 2 All

Dima: Загляни в эту тему http://clipper.borda.ru/?1-0-0-00000304-000-10001-0

p519446: Как раз сегодня, перед этим постом, я эту ветку перечитал. Но там ведь про разгрузку ЦПУ идёт речь, кажется ? А у меня вопрос, имхо, немного "обратный": про НАгрузку :-). То есть, почему ф-ция time() (или seconds()) *** НЕ *** может грузануть ЦПУ при выполнении цикла. И самое загадочное, почему в этом помогает вызов именно "дисковой" функции (да еще только с корректным с тю.зр. DOS-именования файлов аргументом). SUV мне говорил как-то, что время он черпает не с помощью клипперных time()/seconds(), а лезет за ними в BIOS (кажись). Но в упомянутой ветке (http://clipper.borda.ru/?1-0-0-00000304-000-10001-0) он же (SUV) говорит, что: SUV пишет: Использование вместо seconds() своей функции, считывающей время не через сервис DOS, а из области данных BIOS приводит к очевидному замедлению системных часов и еще он пишет, что переделал ядро клиппера с целью нормальной работы seconds(). Вот я и хочу спросить у публики: а без переделки ядра никак эти тормоза не обойти ?

Dima: я пас..........


Sergy: да, офигеть... у меня тоже самое: включение дисковой функции "волшебным образом" ускоряет цикл... Скорость: в первом варианте ~ 1500 итераций/секунду во втором ~ 9600 WinXP + 5.2e + Blinker 6.0 DBFNTX + использую разгрузку через IamIdle() из FT, но на время теста отключал ее нафих.

ort: У меня результаты такие (WinXP + Clipper 5.2e + DosIdle()): - без File() - 15 с - с File("C:\1") - 10 c - с File("C:\<>") - 18-20 c

suv3: p519446 пишет: Как раз сегодня, перед этим постом, я эту ветку перечитал. Но там ведь про разгрузку ЦПУ идёт речь, кажется ? А у меня вопрос, имхо, немного "обратный": про НАгрузку :-). Правильно Дима говорит - перечитай ту ветку. Вопрос у тебя как раз по ней. То есть, почему ф-ция time() (или seconds()) *** НЕ *** может грузануть ЦПУ при выполнении цикла. Не "не может грузануть", а винды, при получении от дос-задачи запроса "скока время", считают, что программе не хрен делать (как при считывании кнопки), а значит, ее можно тормознуть. Процессорное время у задачи принудительно отбирается. То, что дос работает, и то, что системе самой делать не хрен - в расчет не берется. Время просто отбирается - и все. Вызов file("c:\1") помогает. Видимо, при обращении доса к некоторым сервисам, винда понимает, что работа идет и время отбирать не надо. Но не ко всем сервисам. Эксперименты показывали, что при вызове seconds() замедление работы доса происходит даже в случае работы с базами. Считывание времени из BDA может привести к остановке дос-времени (виндовое время продолжает идти). Подробно не описываю - долго. Считывание времени из портов RTC не пробовал. Обнаружил, что если перед считываением счетчика тиков предварительно дернуть сервис клавиатуры - время в BDA обновляется и не замирает. Тем и пользуюсь.

Sergy: Вызов file("c:\1") помогает. Видимо, при обращении доса к некоторым сервисам, винда понимает, что работа идет и время отбирать не надо. Но не ко всем сервисам. Чую одним местом - что не в винде это дело... никто с другим линкером собрать не пробовал ? Мне кажется, дюже умный 6,0 получился, даже не в меру...

Григорьев Владимир: У меня есть такое предположение, которое имеет смысл, если вы собираете программу в защищенном режиме. Вполне возможно, что при вызове DOS прерываний процессору необходимо переключиться из защищенного режима в реальный режим работы. А затем обратно в защищенный. Может быть когда стоит одна функция времени, то процессор постоянно "скачет" из защищенного режима в реальный и обратно. Когда же стоят две функции, то может быть обратный выход из реального в защищенный режим происходит по выходе из цикла? Это лишь мое предположение. Если же вы проверяли это в реальном режиме, то значит я не прав.

suv3: Григорьев Владимир пишет: Вполне возможно, что при вызове DOS прерываний процессору необходимо переключиться из защищенного режима в реальный режим работы. А затем обратно в защищенный. Может быть когда стоит одна функция времени, то процессор постоянно "скачет" из защищенного режима в реальный и обратно. Когда же стоят две функции, то может быть обратный выход из реального в защищенный режим происходит по выходе из цикла? В DPMI для вызова любого прерывания происходит переключение туда-обратно на время прерывания Команда прерывания - привилегированная, при ее обнаружении происходит исключение, которое обрабатывается блинкеровским обработчиком исключений. (dpmi-сервер) Он запоминает, что хотят, переключается в реальный режим, вызывает дос (при этом происходит исключение, которое обрабатывается уже операционной системой), запоминает возвращаемые значения, переключается в защищенный, продолжает выполнение программы со следующей за командой прерывания инструкцией. "Выход из реального по выходу из цикла" - так не бывает

suv3: Sergy пишет: Чую одним местом - что не в винде это дело... никто с другим линкером собрать не пробовал ? Дело в винде. Весь сервис программам дос предоставляется windows-ом. Если ОС считает, что при вопросе "скока время" нужно приостановить дос-задачу и поделать свои мутные дела - значит так тому и быть. И единственный выход - не спрашивать.

p519446: suv3 пишет: винды, при получении от дос-задачи запроса "скока время", считают, что программе не хрен делать (как при считывании кнопки), а значит, ее можно тормознуть. Процессорное время у задачи принудительно отбирается. <...> Вызов file("c:\1") помогает. Видимо, при обращении доса к некоторым сервисам, винда понимает, что работа идет и время отбирать не надо. Но не ко всем сервисам. Профессор, может быть, Вы и правы. Но как объяснить, что при время виндузой отбирается и НЕ отдаётся, даже если далее в цикле (после вызова seconds()) дать команду, которая уж ТОЧНО потребует от ЦПУ некоторого мыслительного процесса. Например, если вызывать математич. функцию: #DEFINE I_MAX 20000 // двадцать тысяч LOCAL R FOR I=1 TO I_MAX K:=TIME() // или K:=SECONDS() -- всё равно R:=LOG( SQRT(I)**2.367+ (I%7)**3.1587 ) NEXT -- то ЦПУ так и останется в нулевой загрузке. Что, виндуза такая "беспощадная", что НЕ отдаёт обратно кванты времени ЦПУ даже для операций в плавающей точкой, если я перед этой операцией спросил её "скока время" ? ЗЫ. Насчет обращений к БД -- согласен. Действительно, виндуза НЕ отдает обратно время даже при команде записи в БД, а также при dbSeek(). В общем, странно всё это. Григорьев Владимир пишет: Если же вы проверяли это в реальном режиме, то значит я не прав. Я проверял в BLI EXE EXT. В реал моде не работаю вообще. Sergy: никто с другим линкером собрать не пробовал ? Мне кажется, дюже умный 6,0 получился, даже не в меру... В блинкере 7.0 та же песня (впрочем, он еще "умнее" 6-го :-)). Собирать линкером causeway не пробовал; но со всеми библами (six, dbfaxs etc) моя прога на нём вываливается по какому-то страшному GPF. Сразу. Ковыряться в причинах не пробовал, некогда. Exospace сборку выполняет чёрт знает сколько времени, так что отпадает.

p519446: Очередные новости. 1) сборка в реал моде *** НЕ *** влияет на быстродействие выполнения цикла; 2) при переводе в полноэкранный режим все начинает работать достаточно БЫСТРО (!). И время работы не зависит от того, запустил ли я .exe через ярлык или через оболочку типа FARa или Volkov Commander. След., виндуза не всегда отбирает у задачи кванты ЦПУ при вопросе "скока щя время"! 3) САМОЕ интересное. Если создать ярлык на этот .exe-шник и зайти в его св-ва, выбрать там вкладку "Разное" и установить бегунок в разделе "Приоритет при ожидании" в КРАЙНЕЕ ЛЕВОЕ положение, то всё начинает летать со 2-ой космической скоростью. При малейшем сдвиге бегунка вправо -- опять тормоза. При попытке сделать то же самое через .bat-файл, дав команду start test.exe /realtime -- снова тормоза (я это давно, кстати, просёк: в виндузе команда start с указанием приоритета не работает для 16-разрядных приложений; таск манагер при указании ЛЮБОГО приоритета всегда показывает для соотв-щего процесса ntvdm.exe приоритет = "Средний"). К сожалению, я не могу считать панацеей способ п. 3 (создание ярлыка на .exe'шник с указанием приоритета при ожидании = MAX). Потому что обычно приложения запускаются в некотором окружении предварительных и завершающих команд, т.е. через .bat-файл (а там как раз эта фишка не работает). И еще потому, что такая задача, запущенная с макс. приоритетом, будет клинить насмерть другие задачи. 4) манипуляции с тем же ярлыком на .exe'шник в разделе свойств "Память" (EMS, XMS, DPMI) бесполезны. Эффект от их изменения нулевой. Какие будут комменты, коллеги ?

p519446: ЗЫ. У кого-нить есть компилятор типа borland C ? если да, то не сочтите за труд, сделайте, плз, аналогичную прогу и запустите её -- что будет ? вдруг все эти "волшебства" происходят вообще не из-за виндузы, а из-за какой-то кривоты в клиппере/блинкере ?!

p519446: ЗЫ-2. Еще один результат: сборка старым клиппером (87) и компоновщиком PLINK86.EXE также приводит к .exe-шнику с тормозами. И также работает способ увеличения до максимального приоритета при ожидании в св-вах ярлыка этого экзешника. Отсюда вывод: блинкер, кажись, тут ни причём.

saulius: природа эффекта: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sag_mpmonperf_25.mspx?mfr=true и http://support.microsoft.com/kb/186560/

suv3: saulius пишет: Но как объяснить, что при время виндузой отбирается и НЕ отдаётся, даже если далее в цикле (после вызова seconds()) дать команду, которая уж ТОЧНО потребует от ЦПУ некоторого мыслительного процесса. Например, если вызывать математич. функцию: #DEFINE I_MAX 20000 // двадцать тысяч LOCAL R FOR I=1 TO I_MAX K:=TIME() // или K:=SECONDS() -- всё равно R:=LOG( SQRT(I)**2.367+ (I%7)**3.1587 ) NEXT -- то ЦПУ так и останется в нулевой загрузке. блин, что же тут непонятного? цпу в нулевой = задаче дают мало времени. причина - она не вызывает никаких сервисов, кроме "скока время"

suv3: p519446 пишет: Какие будут комменты, коллеги ? считывать время функцией xpSeconds(), которую я тебе дал вот и все комменты зы. ссылки на микрософт - не по теме

Dima: suv3 пишет: считывать время функцией xpSeconds() И мне дай пожалуйста ;) !

suv3: куда давать-то

Dima: suv3 пишет: куда давать-то xharbourxСОБАЧКАгмайлмТОЧКАсом



полная версия страницы