Что быстрее в памяти, целых или символах? И отображение файла или чтение чанка? - PullRequest
6 голосов
/ 07 апреля 2010

Хорошо, поэтому я написал (довольно неоптимизированную) программу, прежде чем кодировать изображения в JPEG, однако теперь я работаю с транспортными потоками MPEG-2 и кодированным в них видео H.264.Прежде чем погрузиться в программирование всего этого, мне любопытно, какой самый быстрый способ иметь дело с настоящим файлом.

В настоящее время я сопоставляю файл .mts в память, чтобы работать над ним, хотя яне уверен, будет ли быстрее (например) считывать 100 МБ файла в память порциями и обрабатывать его таким образом.

Эти файлы требуют большого количества битовых сдвигов и таких для чтения флагов,поэтому мне интересно, когда я ссылаюсь на часть памяти, если это быстрее, чтобы прочитать 4 байта сразу как целое число или 1 байт как символ.Мне показалось, что я где-то читал, что процессоры x86 оптимизированы до 4-байтовой детализации, но я не уверен, что это правда ...

Спасибо!

Ответы [ 5 ]

6 голосов
/ 07 апреля 2010

Файлы с отображением в памяти обычно являются самыми быстрыми доступными операциями, если вы хотите, чтобы ваш файл был доступен синхронно.(Существуют некоторые асинхронные API, которые позволяют O / S иногда переупорядочивать вещи для небольшого увеличения скорости, но это звучит так, как будто это не помогает в вашем приложении)

Основное преимущество, которое вы получаете с сопоставленными файламизаключается в том, что вы можете работать с памятью над файлом, пока он все еще считывается с диска с помощью O / S, и вам не нужно управлять своим собственным кодом чтения файла блокировки / потоков.

Справочник по памятив памяти x86 будет считываться целая строка за раз, независимо от того, с чем вы на самом деле работаете.Дополнительное время, связанное с небайтовыми гранулярными операциями, относится к тому факту, что целые числа не должны быть выровнены в байтах.Например, выполнение ADD займет больше времени, если вещи не выровнены по 4-байтовой границе, но для чего-то вроде копии памяти будет небольшая разница.Если вы работаете с собственно символьными данными, то сохранить их будет быстрее, чем читать все как целые числа и сдвигать биты.

Если вы выполняете кодирование узкого места h.264 или MPEG2в любом случае, вероятно, будет время процессора, а не дисковый ввод-вывод.

2 голосов
/ 07 апреля 2010

Если вам нужен доступ ко всему файлу, всегда быстрее прочитать его в память и выполнить там обработку. Конечно, это также тратит впустую память, и вы должны как-то заблокировать файл, чтобы не получить параллельный доступ к другому приложению, но оптимизация в любом случае связана с компромиссами. Отображение памяти происходит быстрее, если вы пропускаете (большие) части файла, потому что тогда вам вообще не нужно их читать.

Да, доступ к памяти с 4-байтовой (или даже 8-байтовой) степенью детализации быстрее, чем доступ к ней по байтам. Опять же, это компромисс - в зависимости от того, что вы будете делать с данными впоследствии, и от того, насколько хорошо вы разбираетесь с битами в int, в целом это может быть не быстрее.

Что касается всего, что касается оптимизации:

  1. мера
  2. 1010 * оптимизируют *
  3. мера
1 голос
/ 07 апреля 2010

Это последовательные битовые потоки - вы в основном используете их по одному за раз без произвольного доступа.

Вам не нужно прилагать много усилий для явной буферизации чтения и тому подобного в этом сценарии: операционная система все равно будет буферизировать их для вас. Я уже писал парсеры H.264, и время полностью зависит от декодирования и манипуляции, а не от ввода-вывода.

Моя рекомендация - использовать стандартную библиотеку и анализировать эти битовые потоки.

Flavor - это такой синтаксический анализатор, и на сайте даже есть примеры MPEG-2 (PS) и различных частей H.264, таких как M-Coder , Flavor создает собственный код синтаксического анализа на языке, похожем на c ++; Вот цитата из спецификации MPEG-2 PS:

class TargetBackgroundGridDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 7 
{
    unsigned int(14) horizontal_size;
    unsigned int(14) vertical_size;
    unsigned int(4) aspect_ratio_information;
}

class VideoWindowDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 8 
{
    unsigned int(14) horizontal_offset;
    unsigned int(14) vertical_offset;
    unsigned int(4) window_priority;
}
0 голосов
/ 07 апреля 2010

В отношении файлов отображения памяти следует учитывать, что файл с размером, превышающим доступный диапазон адресов, сможет отображать только часть файла. Для доступа к оставшейся части файла требуется, чтобы первая часть была не отображена, а следующая часть отображена вместо нее.

Поскольку вы декодируете потоки MPEG, вы можете использовать двойной буферизованный подход с асинхронным чтением файла. Это работает так:

blocksize = 65536 bytes (or whatever)
currentblock = new byte [blocksize]
nextblock = new byte [blocksize]
read currentblock
while processing
   asynchronously read nextblock
   parse currentblock
   wait for asynchronous read to complete
   swap nextblock and currentblock
endwhile
0 голосов
/ 07 апреля 2010

Что касается наилучшего размера для чтения из памяти, я уверен, что вам понравится этот пост о производительности доступа к памяти и эффектах кэша.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...