Во-первых, на 32-битной платформе ваш жесткий лимит использования адресного пространства будет где-то около 2 ГБ (но, возможно, намного меньше) - при условии, что вы сохраняете все это за раз. Лучше предположить, что вы не сможете получить больше, чем, может быть, 512 МБ в непрерывной памяти и 1-1,5 ГБ или около того в несмежной памяти (т. Е. Делая несколько небольших сопоставлений). Скорее всего, это ваша проблема; вы исчерпали смежное адресное пространство. Аппаратное обеспечение в свою очередь ограничено (для процессоров Intel) где-то около 16 ГБ памяти для 32-битной системы. И вы действительно действительно не хотите обмениваться. Таким образом, это означает, что у вас есть один из нескольких вариантов:
- Используйте 64-битную систему и действительно большой массив (простой и быстрый, требует много памяти).
- Используйте 32-битную систему и взломайте, чтобы обойти ограничения адресного пространства. Это означает, что вам нужно создавать объекты общей памяти и отображать только часть пространства за раз. В Windows вы можете использовать для этого анонимный объект сопоставления файлов - в основном это разделяемая память с пустым именем. В Linux вам нужно сначала увеличить максимальный размер / dev / shm, затем использовать
shm_open
и mmap
. (сложный, почти такой же быстрый, как 64-битный, если все сделано правильно. Минимизируйте количество повторных отображений, которые вы делаете. Все еще требуется много памяти)
- Использовать файлы на диске. Только реальная опция с SSD ; на реальном диске поиск займет слишком много времени, чтобы быть практичным. По сути, вы просто будете искать по файлу и записывать столбцы данных за раз. (Относительно медленно, но не слишком сложно. Требуется SSD. Минимальные требования к памяти)
- Сделайте несколько проходов. Вы можете выбрать группу выходных кадров для хранения в памяти одновременно; декодируйте все видео, пропуская части, которые соответствуют кадрам, которые вы еще не храните в памяти. Как только вы закончите текущий набор кадров, запишите их на диск и начните заново, расшифровывая видео с нуля, с новым набором выходных кадров. Это хорошо подходит для массового параллелизма - вы можете отключить каждый выходной набор на другом отдельном компьютере для выполнения работы, а затем соединить их все вместе в конце. (умеренно сложный; медленный; меняет процессорное время на память. Может быть очень быстрым, если распараллелен).
Первые два варианта хороши, если у вас достаточно памяти для хранения всего выходного видео. В идеале вы хотите пойти по 64-битному маршруту; переназначение окон совместно используемой памяти - дорогостоящая операция, и вы будете много заниматься этим.
С четвертым вариантом может быть сложно узнать, каков предел памяти. Я бы порекомендовал выполнить бинарный поиск с использованием тестовых выделений, чтобы выяснить, сколько места в вашем адресном пространстве вы можете использовать (вы должны использовать низкоуровневые вызовы выделения, чтобы избежать накладных расходов кучи, обратите внимание). Обратите внимание, что если вы не будете осторожны, это может не оставить адресного пространства для вашего видеодекодера - вероятно, было бы лучше вычесть или около того 100 МБ из результата и перераспределить его, чтобы освободить место для нормальной кучи. Вы также должны быть осторожны, чтобы не превышать общую физическую память, чтобы избежать попадания в своп.
Не зная вашей ОС и из какой библиотеки вы получаете этот класс Surface
, трудно быть более точным в отношении того, как его проверять, но вам действительно следует избегать сохранения его в обычной куче, просто чтобы избежать ошибок выделения. в другом коде, который, возможно, не приспособлен для работы с OOM.
В качестве примечания вы можете повернуть выходные кадры на 90 градусов при их подготовке (то есть поместить их в основной порядок столбцов ). Затем вы можете повернуть их обратно в качестве последнего прохода после создания всех необработанных изображений (или даже при кодировании из необработанных данных изображений в сжатый формат). Это особенно важно, если вы решите использовать дисковый маршрут с SSD - это поможет избежать ненужных операций чтения и записи, так как в случае основного порядка строк (обычный порядок для видео) вам придется пропустить пиксели для других столбцов всякий раз, когда ты пишешь один. Однако при работе в оперативной памяти это все еще полезно, поскольку улучшает локальность кэша.