Участник
Регистрация: 28.11.2005
Адрес: Москва
|
Цитата:
Сообщение от fed
А ты случайно не разбирался как сам ax32serv работает с объектами синхронизации ? У меня просто есть подозрение, что рекомендация использовать на AOS-серверах не больше двух процессоров, вызвана тем, что в недрах ax32server есть Big Kernel Lock, который приводит к тому, что в реальных условиях система плохо масштабируется на более чем два процессора на компе.
По правде сказать, особо не разбирался... Если же взглянуть поверхностно, то выходит вот что.- ax32serv.exe версии KR2 импортирует следующие функции синхронизации:
- CreateEvent, SetEvent;
- InitializeCriticalSection, InitializeCriticalSectionAndSpinCount, EnterCriticalSection, TryEnterCriticalSection, LeaveCriticalSection, DeleteCriticalSection;
- CreateMutex, OpenMutex, ReleaseMutex;
- WaitForMultipleObjects, WaitForSingleObject;
- InterlockedExchange, InterlockedIncrement, InterlockedDecrement;
при этом InitializeCriticalSectionAndSpinCount используется вместо InitializeCriticalSection в 1-м месте С-шной RTL и в 1-м месте собственно AOS'ом - и почему-то через GetProcAddress; неужели разработчики расчитывали на запуск AOS'а под Win95 или WinNT4 до SP3? ну да ладно...
- функции Interlocked* нас не интересуют, поскольку серьезных блокировок они создать не могут;
- WaitForMultipleObjects используется в одном месте для одного объекта (дескриптора hThread) с таймаутом 5 сек., при этом код, вызывающий эту функцию, занимается закрытием сокетов;
- взаимоисключения (Mutex) используются, видимо, только библиотекой SmartHeap: в одном случае создается (и потом запрашивается) глобальный Mutex с именем "SmartHeap601MutexMovShrName", в другом создаются взаимоисключения с именами формата "SHI%lX", где %l получается генератором случайных чисел, а полученный дескриптор взаимоисключения сохраняется в свойстве динамически создаваемого объекта, т.е. не является неким глобальным объектом;
- критические секции используются очень широко и зачастую являются свойством того или иного динамически создаваемого объекта; возможно, есть глобальные критические секции. Мне с полпинка встретилась одна, используемая 3-мя разными функциями для выполнения очень небольших кусков кода, как правило, прописывания в свойстве динамически созданного объекта адреса другой (созданной для него?) критической секции;
- события (Event) - тут начинается самое "веселое". Мне встретились как минимум 5 глобальных Event'ов, правда, один из них "дергается" в обработчике RestoreUnhandledExceptionFilter() и, видимо, относится к RTL. Но самое поганое (или просто недоступное моему пониманию на том уровне, на котором я "знаю" использующий их код) - это то, как происходит работа с этими глобальными объектами. Обычно события используются при ожидании того, когда они перейдут в мнэ.. сигнальное (signaled) состояние, либо пока не истечет какой-то таймаут. Так вот, как минимум два из найденных пяти глобальных собыий, по ходу, никогда не переходят в сигнальное состояние (я не нашел вызовов SetEvent, где они передавались бы в качестве параметров). Одно из этих двух глобальных событий монопольно используется одной функцией, которая просто вызывает на нем WaitForSingleObject с переданным в параметре таймаутом и фактически эквивалентна Sleep(). Эта функция вызывается из 14 различных мест с таймаутами в среднем 250-500мс, при этом одно из мест, откуда она вызывается, - это функция-заглушка, которая просто передает ей параметры и, в свою очередь, вызывается еще из 9 различных мест. Выглядит это, скажем так, непонятно.
В общем, код, использующий объекты синхронизации, работает местами очень загадочно... Два из пяти найденных глобальных событий, которые все же переходят при определенных условиях в сигнальное состояние, могут претендовать на роль «Big Kernel Lock», но для подтверждения этого нужно копать более тщательно. Плюс еще неизвестно, какая версия библиотеки SmartHeap используется Аксаптой. Насколько я знаю, есть отдельная версия SmartHeap SMP для многопроцессорных машин, так вот не факт, что использована именно она.
Цитата:
Сообщение от fed
Примерно как в ядрах Linux до версии 2.2.x. Там, фактически, все ядро было неповторновходимым, поэтому в теории систему можно было использовать на любом количестве процессоров, но из за того что само ядро было критическим ресурсом, в реальных ситуациях использования Linux (с нормальным вводом-выводом короче говоря), ставить больше двух процессоров было бесполезно.
На счет линукса не скажу, но что-то схожее было в Win9x, в частности, Matt Pietrek в "Секретах программирования под Windows 95" писал про некий глобальный Mutex, из-за которого в Win9x были проблемы с эмуляцией вытесняющей многозадачности Кажется, это было отчасти связано с кодом GDI, унаследованным от Win 3.1, с кучей ручных оптимизаций, использующих глобальные переменные, по причине которых этот код стал по большей части "нереентерабельным".
Последний раз редактировалось gl00mie; 24.10.2007 в 00:59.
|