Столкнулся с проблемой - при выгрузке большого (1ГБ и больше) файла в память (мапирование) возникают проблемы- невозможно такой файл промапировать, если тредов в основной процедуре больше трех. Искал доки в нете - везде пояснеия типа "потоки делят память между собой" Как делят? Тупо по количству потоков на уровне компиляции (4/1, 4/2,4/3, 4/4 4/5.... ГБ)? Возможно ли задать треду в winapi32 объем памяти /стартовый конечный адресс/, в рамках которой он может исполняться? Подозреваю, что в 64-битных ОС такой проблемы невозникнет, но нужно реализовать под ХР 32 битной. ЗЫ - Спасибо всем, кто ответит!
"Делят" в смысле используют общее адресное пространство (АП) процесса. По умолчанию каждый поток лишь "тупо" откусывает у процесса 1Мб адресов под свой стек (плюс мелочевка в виде одной 4К страницы под служебную инфу - TEB). Динамическая же память (маппинг, VirtualAlloc, HeapAlloc) выделяется из свободного АП процесса независимо от того какой поток ее запросил. "Проблема" только в том, что в 32-битной винде юзермодному процессу доступно не 4, а только 2Гб памяти, и к тому же часть из нее занята образами самого процесса и загруженных сис.длл, кучей процесса, стеками потоков и различными служебными регионами памяти. Причем эта память занимает не непрерывный диапазон адресов, а раскидана кусками с пропусками\дырками, т.е. фрагментирована. В итоге в зависимости от количества и "качества" подгруженных длл максимальный размер непрерывного диапазона свободных адресов может составлять всего от 1.7-1.8Гб в лучшем случае, до 1-1.2Гб и даже менее в худшем (если какой-то дурной длл вздумается влезть посреди АП). Глянь распределение памяти своего процесса (например, ProcessExplorer'ом, OllyDbg и т.п.) и посмотри есть ли там непрерывный свободный кусок нужного тебе размера "1ГБ и больше"
2 klzlk Кусками мапить мне "негодно", потому как нефиг пытаться быть умней ОС (Винду сам нелюблю, но приходится пользовать /при "сквозной" индексации удобней целым файлом/.) -когда ей нужно просвопирует. Единственая проблема, судя по комментам Leo - фактическая адрессация 2ГБ. Но ,ежели вместо тредов пускаю выполнение куска маппирования через процедуру - неудобств с загрузкой нужного куска файла не возникает. (Потому и думаю, что есть нечто недокуменированое (на уровне компилятора Masm32))/Но прервать / посмотреть результаты деятельности просчета нет никакой возможности. Возможно у меня глюк в подходе к перехвату сообщений WM. (Реализованы все области редактирования, кнопки и т.д. через CreateWsndow) Мапирование - всегда отдельным потоком (или процедурой), unmap использую всегда. Возможно CloseFile при этом является необходимым?
Проблема не в подкачке. Нет приоритета адресов(тоесть можно урезать верхние адреса ап, но тут не существенно). Всякий запрос на аллокацию может привести к выделению памяти по случайному адресу. Так как для проецирования необходима линейность адресного пространства, то выделенный регион в пределах проецируемого отклонит запрос на аллокацию. Маловероятно что в GUI приложении вы найдёте непрерывный регион в 1GB. Проецировать секции следует порциями.