быстрый кусок памяти

Тема в разделе "WASM.ASSEMBLER", создана пользователем cresta, 12 июн 2005.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Есть такое желание: получить максимально быстро кусок памяти, причём памяти быстрой (в смысле чтения/записи).

    Такие вещи, как VirtualAlloc нежелательны, т.к. выделяют память (с последующей очисткой) долго, порядка 3000 тактов. Остается два способа: .data? и стек.

    .data? вроде неограничен в размерах, но медленней, а стек быстрее, но как из него выдавить порядка 16 кБ - не знаю :dntknw: До 10 кБ вроде устойчиво работает

    sub esp,10000

    mov [esp+5000],eax

    add esp,10000

    а больше - падает. Равно как и LOCAL var[10000] :BYTE. Можно ли снять это ограничение? Без всякого рода апи. Пытался ключем /F 10000 - безуспешно.
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    cresta

    Four-F постил пример выделения большого объема памяти в стеке, ищи по форуму
     
  3. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    BSS, который .data?, ничем существенно не отличается от VirtualAlloc.





    Макрос LOCAL складывает размеры всех локальных переменных и вычитает результат из esp, т.е. генерирует sub esp,10000.



    PS: А хип (HeapAlloc) юзать не пробовали?
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix

    Видел эти ссылки, но там мало памяти, а проходить через исключения и получать новую страницу - долго. Экзотические способы вроде CreateThread - совсем медленно :dntknw:



    Quantum

    Цепочка

    invoke GetProcessHeap

    mov ebx,eax

    invoke HeapAlloc,ebx,HEAP_ZERO_MEMORY,16384

    invoke HeapFree,ebx,HEAP_NO_SERIALIZE,eax

    это ещё медленней, чем VirtualAlloc.



    Так что, получается, максимум устойчивого стека - две страницы?
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    А флаг HEAP_ZERO_MEMORY действительно нужен?
     
  6. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    cresta

    Не очищая память все равно не выйдет. Даже на стеке - когда стек будет расширяться память должна быть очищена. Почему? Потому что это не секюрно - система должна или очистить память или быть уверена что она никогда не использовалась на запись, потому что там может остаться что угодно - в том числе и пароли. Если такой подход не нравится - придется патчить систему или если линукс - подправить кернел =).
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Quantum

    HEAP_ZERO_MEMORY - это как индикатор, была сделана запись в ячейку или нет, без этого флага быстро получается, но потом надо самому забивать память. Чуть быстрее, но не принципиально.



    semen

    Не понял, если выходим из процедуры, add esp,... достаточно ведь, зачем ещё что-то? Стек нам никто чистым не предоставляет, так чего его за собой чистить? Пусть система считает, что это от её предыдущего выделения остался мусор :)



    Видимо придётся таки в .data? кусок брать. Чуть медленней работать, но получаешь мгновенно.
     
  8. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    .data? -- лучшее, что можно предложить. Стек может быть ограничен в размере. А .data? (bss) может быть очень большой. Выделяет эту память винда, освобождает при завершении проги тоже... халява! Если нужна скорость, то можно пробежаться по страницам и сделать pagein. Для особо тяжелых случаев можно заблокировать эту память, чтобы винда ее в своп не скинула.
     
  9. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Если размер памяти большой (20Mb и более) то лучше использовать секцию ниинициализированных данных в PE. Каков максимально допустимый размер такой секции - сложно сказать, вполне возможно, что начиная с какого-то значения будут проблемы с запуском на некоторых версиях виндоса/конфигурациях системы. Если памяти нужно меньше - можно использовать стэк, предварительно (например, при старте проги) пробежаться по всем 4K страницам, что бы случаем exception не выскочил.
     
  11. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix

    Третью ссылку я до этого не видел, но там подмена опять таки через вызовы апи, а это время :dntknw:



    _BC_, S_T_A_S_



    Мне в принципе много не надо (порядка 16 кб), главное, чтобы под рукой всегда было. При запуске подергать за страницы тоже не удастся - код будет в либе, а вызывать фунцию, которая только этим и занималась бы при запуске (типа init_lib_memory) - не знаю, нужно ли это.

    Видимо .data? остается как единственный приемлимый вариант.

    Спасибо всем.
     
  12. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Для 16 кб - стэк как раз самое то ;) Он всегда под рукой и не имеет проблем как у глобальных данных.

    добавить в точку входа
    Код (Text):
    1.  
    2.      mov     ecx, 16384/4
    3.      mov     eax, esp
    4. repeat:
    5.      push    0
    6.      loop    repeat
    7.      xchg    esp, eax
    8.  
    хотя лучше код немного увеличить и обращаться не к каждому dword, а только к страницам.
     
  13. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    cresta

    add esp,... не достаточно - еще нужна защита от переполнения (тест чтобы не перелететь stack guard page). Иначе зачем С crt вызывает __chkstk при больших аллокациях стека? Чтобы обратиться к каждой новой странице стека и обработчик исключения уже непосредственно аллокирует страницы (сразу весь дефолтный мегабайт стека ведь не выделяется). Если система просто будет аллокировать память - я создам много тредов с большим стеком и буду в нем искать пароли от тока что закрывшегося админского процесса из под обычного юзера. Можно и не обнулять - но быть уверенным что никакой процесс сюда данные не записывал НАДО.

    А секции все равно инициализируются нулями при старте процесса - так что тоже самое что и VirtualAlloc.
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    S_T_A_S_

    Это кусок пожрал 16000 тактов :dntknw: Вся процедура, которой нужна эта память, примерно столько работает. Видимо винда со своим диспетчером памяти вклинилась :)



    semen

    ну её к чёрту, эту винду с её маниакальной секретностью :)
     
  15. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    cresta

    Линукс такой-же секретный. Но его поправить легче...

    Например недавно найденная дыра в линукс + хипертрединг как раз и заключалась в возможности прочитать память другого процесса из-за данной реализации поддержки хипертрединга в кернеле (если мне память не изменяет).
     
  16. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    w2ksp4:

    VirtualAlloc(MEM_COMMIT) ~1500 на 16Кб

    HeapAlloc(HEAP_NO_SERIALIZE) ~5000 на 16Кб

    HeapAlloc(HEAP_ZERO_MEMORY) ~30000-60000 на 16Кб



    Надо мерять разные способы, и определять будет ли вся выделенная память в L1 или делать префетч самому
     
  17. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    bogrus

    мерял конечно:

    VirtualAlloc(MEM_COMMIT) ~3200

    HeapAlloc(HEAP_NO_SERIALIZE) ~400

    HeapAlloc(HEAP_ZERO_MEMORY) ~4500

    Похоже, альтернативы неинициализированной секции нет
     
  18. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    cresta >




    Этот кусок не расчитан на скорость, поскольку на каждые 4K делается 999 лишних итераций цикла :) Да я и не пойму, зачем ему скорость - он вызывается один раз при старте проги.
     
  19. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Компилятор вот так делает:


    Код (Text):
    1.         push    ebp
    2.         mov ebp, esp
    3.         and esp, 0FFFFFFF8h
    4.         mov eax, 12ECh
    5.  
    6. test_pages: sub esp, 1000h
    7.         sub eax, 1000h
    8.         test    [esp], eax
    9.         cmp eax, 1000h
    10.         ja  short test_pages
    11.         sub esp, eax
     
  20. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    S_T_A_S_



    Даже один раз не хочется делать :) Если при запуске делать, то можно тот же VirtualAlloc сделать, и держать эту память до конца работы программы. А так хотелось найти уже готовое место, на халяву :)