Всегда был уверен что VirtualAlloc с флагом MEM_RESERVE это очень "легкая" операция - системе всего-то и нужно пометить указанную часть адресного пространства текущего процесса как "занятое", чтобы случайно не залазить в него. А последующий MEM_COMMIT в зарезервированной области - простая и красивая возможность избежать конфликта адресов с системой. Теперь решил это проверить и с удивлением обнаружил, что время "резервирования" и время "выделения" 10 Мб памяти по адресу определяемому системой примерно одинаково, хотя в первом случае системе вроде бы как вообще не нужно думать о сопоставлении адресам страниц памяти. Но это ещё не самое интересное - последующее выделение памяти в зарезеревированном диапазоне адресов происходит в 50-100 раз медленнее чем когда адрес определяется системой. Интересно это только в XP SP3 или везде так? и с чего это вообще так происходит? зы: исправленный тестер в #30
Clerk cpuid вроде бы как заставляет завершиться все предшествующие инструкции перед замером времени - здесь это не важно, но макрос универсальный.
cpuid тут не нужна совсем, ты с помощью неё сигнатуру процессора считываешь. Вот у меня результат(XPSP2, P4): [Я через это img407.imageshack.us картинку прилипил, но снизу какаято надпись, это так и должно быть ?]
Clerk эм... возможно я ошибаюсь, но тут на васме ранее пробегала инфа, что перед rdtsc нужно выполнять cpuid чтобы CPU выполнил команды именно в заданной последовательности. кажецца в статьях это было упомянуто
Y_Mur Флаг MEM_COMMIT обязан(!) быть в паре с MEM_RESERVE(!) для правильной работы ф-ий - это тонкость реализации такая техническая. Желающим проверить: попробуйте выделить новую порцию памяти по адресу, который был MEM_RELEASE'ед после одинокого MEM_COMMIT флага. Эта "особенность" присутствует на ХР2/3.
Clerk Этот либо не этот код тут непричём. Это механизм более=менее честного посчёта тиков. Включает в себя сериализацию инструкций перед замером тактов, затем вычетание cpuid и rdtsc тактов из конечного значения тактов.
asmfan Ну а какая разница, что есть cpuid, что её нет - это ничего не изменит. Да есчо и ведь этот кодес в юзермоде выполняетсо при включенном планировании.
Clerk http://www.wasm.ru/forum/viewtopic.php?pid=261885#p261885 так я приоритет и поднимаю чтобы минимизировать вероятность пакостей со стороны планировщика, это конечно не панацея, но думаю здесь мера достаточная asmfan это означает только то, что винда не разрешает "самовольно" захватывать адреса даже если на наш взгляд этот адрес свободен ) и требует обязательного согласования, которое может заключаться либо в предварительном использовании флага MEM_RESERVE либо в указании нулевого адреса в MEM_COMMIT. В этом случае винда считает, что её права распоряжаться всем и вся не ущемлены и без проблем заново commit-тит свежеосвобождённый блок памяти ) Так что флаг MEM_COMMIT вовсе не обязан быть в паре с MEM_RESERVE и MEM_RESERVE реально нужен лишь для растущих и разреженных массивов, которым настоящая память выделяется не сразу, а по мере необходимости (и Рихтер о том же пишет). Только непонятно почему в этом случае такие дикие тормоза по сравнению с выделением памяти сразу большим куском. У Clerk, время ещё более менее вменяемое, хотя 1Мб выделяется в 2 раза медленне чем 10Мб, а 9Мб в 5 раз медленнее, а у меня вообще: VirtualAlloc (system address, commit 10Mb) 0:2963 VirtualAlloc (system address, reserve 10Mb) 0:2906 VirtualAlloc (commit 1Mb in reserve) 0:21175 VirtualAlloc (commit 9Mb in reserve) 0:133977
Плохое объяснение багов виндовых ф-й. после RELEASE с успешным исходом bool==1 вызов Alloc с параметром [h_mem_1] (в вашей нотации, хотя [p_mem_1] более правильно) не срабатывает, хотя страница (да даже целый диапазон высвободили успешно).
asmfan я не проверял, но уверен что не сработает и если сразу коммитить этот "свободный" адресок без его предварительного выделения/освобождения - и дело тут как раз не в багах а в неуёмном желании контроля со стороны винды - ты думаешь адресок только что успешно освобождён, а винда говорит, "а вдруг его только что уже другой поток занял?, а если и не занял - всё равно не дам из принципа )"
Y_Mur Впрочем, как и любая другая инструкция .D Чтобы знать почему медленно работает выделение памяти нужно смотреть в сорсах, как это ось делоет.)
Реально память будет выделена не при вызове VirtualAlloc, а при первой попытке доступа к выделенной памяти. Можешь убедиться в этом, сделав несколько раз memset на выделенной памяти и замеряя их время.
Clerk Судя по существенно разному времени при всего лишь смене SP 2 на 3 там что-то сильно поменяли, но всё равно как то оно не хорошо сделано Maratyszcza это я знаю и даже ссылку в первом посте привёл, только это никак не связано со временем работы самой функции VirtualAlloc.
Собственно вопрос "почему так?" вторичен, поскольку исправлять винду я всё равно не буду Больше интересует вопрос "везде ли так?" пока что (спасибо Clerk) понятно что в XP sp 3 по сравнению с sp 2 сильно ускорили выделение\резервирование памяти по системно-определяемому адресу, при этом непонятно - выделение по предварительно заререзервированному адресу толи не трогали (время выделения 1Мб примерно одинаково), толи замедлили (результат на 9Мб, но это может быть и какой-нибудь побочный эффект). Код (Text): sp 2 sp 3 VirtualAlloc (system address, commit 10Mb) 0:15173 0:2913 VirtualAlloc (system address, reserve 10Mb) 0:24037 0:2820 VirtualAlloc (commit 1Mb in reserve) 0:34335 0:28796 VirtualAlloc (commit 9Mb in reserve) 0:75840 0:155647 А как в висте и других? потестите пожалуйста у кого что есть. В аттаче версия теста, которая сразу помещает результат в буфер обмена. зы: исправленный тестер в #30