время выполнения VirtualAlloc

Тема в разделе "WASM.WIN32", создана пользователем Y_Mur, 20 дек 2008.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Всегда был уверен что VirtualAlloc с флагом MEM_RESERVE это очень "легкая" операция - системе всего-то и нужно пометить указанную часть адресного пространства текущего процесса как "занятое", чтобы случайно не залазить в него. А последующий MEM_COMMIT в зарезервированной области - простая и красивая возможность избежать конфликта адресов с системой. Теперь решил это проверить и с удивлением обнаружил, что время "резервирования" и время "выделения" 10 Мб памяти по адресу определяемому системой примерно одинаково, хотя в первом случае системе вроде бы как вообще не нужно думать о сопоставлении адресам страниц памяти. Но это ещё не самое интересное - последующее выделение памяти в зарезеревированном диапазоне адресов происходит в 50-100 раз медленнее чем когда адрес определяется системой.
    Интересно это только в XP SP3 или везде так? и с чего это вообще так происходит?

    зы: исправленный тестер в #30
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Y_Mur
    Для чего ты юзоешь cpuid ?
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Clerk
    cpuid вроде бы как заставляет завершиться все предшествующие инструкции перед замером времени - здесь это не важно, но макрос универсальный.
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    cpuid тут не нужна совсем, ты с помощью неё сигнатуру процессора считываешь.
    Вот у меня результат(XPSP2, P4):
    [​IMG]
    [​IMG]
    [Я через это img407.imageshack.us картинку прилипил, но снизу какаято надпись, это так и должно быть ?]
     
  5. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    Clerk
    эм... возможно я ошибаюсь, но тут на васме ранее пробегала инфа, что перед rdtsc нужно выполнять cpuid чтобы CPU выполнил команды именно в заданной последовательности. кажецца в статьях это было упомянуто
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    RamMerLabs
    Линк на стотью пожалусто дай.
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Да cpuid инструкция сериализации +непревилегированная; об этом в мануалах в описании rdtsc пишут.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    asmfan
    Что не привилегированная это понятно, но зачем она в этом коде, обьясните мне на пальцах.
     
  9. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Y_Mur
    Флаг MEM_COMMIT обязан(!) быть в паре с MEM_RESERVE(!) для правильной работы ф-ий - это тонкость реализации такая техническая.
    Желающим проверить: попробуйте выделить новую порцию памяти по адресу, который был MEM_RELEASE'ед после одинокого MEM_COMMIT флага.
    Эта "особенность" присутствует на ХР2/3.
     
  10. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Clerk
    Этот либо не этот код тут непричём. Это механизм более=менее честного посчёта тиков. Включает в себя сериализацию инструкций перед замером тактов, затем вычетание cpuid и rdtsc тактов из конечного значения тактов.
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    asmfan
    Ну а какая разница, что есть cpuid, что её нет - это ничего не изменит. Да есчо и ведь этот кодес в юзермоде выполняетсо при включенном планировании.
     
  12. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    out-of-order execution и проч.
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    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
     
  14. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Плохое объяснение багов виндовых ф-й. после RELEASE с успешным исходом bool==1 вызов Alloc с параметром [h_mem_1] (в вашей нотации, хотя [p_mem_1] более правильно) не срабатывает, хотя страница (да даже целый диапазон высвободили успешно).
     
  15. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    asmfan
    я не проверял, но уверен что не сработает и если сразу коммитить этот "свободный" адресок без его предварительного выделения/освобождения - и дело тут как раз не в багах а в неуёмном желании контроля со стороны винды - ты думаешь адресок только что успешно освобождён, а винда говорит, "а вдруг его только что уже другой поток занял?, а если и не занял - всё равно не дам из принципа :))"
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Y_Mur
    Впрочем, как и любая другая инструкция .D
    Чтобы знать почему медленно работает выделение памяти нужно смотреть в сорсах, как это ось делоет.)
     
  17. Maratyszcza

    Maratyszcza New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    32
    Реально память будет выделена не при вызове VirtualAlloc, а при первой попытке доступа к выделенной памяти. Можешь убедиться в этом, сделав несколько раз memset на выделенной памяти и замеряя их время.
     
  18. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Clerk
    Судя по существенно разному времени при всего лишь смене SP 2 на 3 там что-то сильно поменяли, но всё равно как то оно не хорошо сделано ;)

    Maratyszcza
    это я знаю и даже ссылку в первом посте привёл, только это никак не связано со временем работы самой функции VirtualAlloc.
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Y_Mur
    Протрассируй сервис/исключение и посмотри где места, которые долго исполняются.
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Собственно вопрос "почему так?" вторичен, поскольку исправлять винду я всё равно не буду ;)
    Больше интересует вопрос "везде ли так?" пока что (спасибо Clerk) понятно что в XP sp 3 по сравнению с sp 2 сильно ускорили выделение\резервирование памяти по системно-определяемому адресу, при этом непонятно - выделение по предварительно заререзервированному адресу толи не трогали (время выделения 1Мб примерно одинаково), толи замедлили (результат на 9Мб, но это может быть и какой-нибудь побочный эффект).
    Код (Text):
    1.                          sp 2        sp 3
    2. VirtualAlloc (system address, commit 10Mb)  0:15173     0:2913
    3. VirtualAlloc (system address, reserve 10Mb) 0:24037     0:2820
    4. VirtualAlloc (commit 1Mb in reserve)        0:34335     0:28796
    5. VirtualAlloc (commit 9Mb in reserve)        0:75840     0:155647
    А как в висте и других? потестите пожалуйста у кого что есть.
    В аттаче версия теста, которая сразу помещает результат в буфер обмена.

    зы: исправленный тестер в #30