@ Дерек предоставил следующую дополнительную информацию:
(время выполнения) ... "больше минуты, по сравнению с 10 - 14 секундами раньше. Хотя я не делаю никаких особых потоков, хотяУ меня есть некоторые прагмы OpenMP. Перемещение ввода-вывода за пределы цикла фильтра не изменило ни одного из них. Я использую CentOS 5.5. Размер изображения составляет около 72 МБ "
огромная разница во времени выполнения.Поскольку используется OpenMP, мы можем предположить, что существует несколько потоков.Поскольку вы имеете дело только с 72 МБ данных, я не могу понять, как разница во времени ввода-вывода может быть такой большой.Мы можем быть уверены, что время чтения меньше, чем ваши исходные 10-14 секунд, поэтому, если у вас нет ошибки в этой части кода, дополнительное время находится в разделе фильтра.Изображения предположительно двоичные?Поскольку @Satya предложила профилировать ваш код или хотя бы добавить некоторые распечатки времени, это может помочь определить, в чем заключается проблема.
«Преимущество» чтения в цикле может быть:
- ОС дает вам некоторый параллелизм, потому что она способна выполнять некоторые операции ввода-вывода параллельно с вашими вычислениями, например, чтение вперед.Вы теряете этот параллелизм, когда читаете все заранее, фактически блокируя во время чтения.
- Считанные данные находятся в кеше в тот момент, когда ваш фильтр обращается к данным.Промахи в кеше могут реально снизить производительность, если обработка невелика относительно пропускной способности памяти.Трудно поверить, что это имело бы существенное значение в этом случае использования, потому что дисковый ввод-вывод намного медленнее, чем память.
Учитывая ваше последнее обновление, похоже, мы имеем дело с # 2.Однако следует обратить внимание на шаблоны доступа к памяти (включая все потоки). Возможно, вы наблюдаете переполнение кэша, поскольку данные, которые раньше использовались в основной памяти, теперь находятся дальше друг от друга.Это может оказать большое влияние, потому что, если у вас много обращений к памяти, и все они пропускают кэш, вы всегда несете затраты на дальнейший доступ к данным, что может быть разницей в порядок.
Решением этой проблемы является размещение вашей памяти в виде полос, например, n строк первого изображения, затем n строк второго изображения, а затем n строк третьего изображения.IIRC эта техника называется «чередование».Точный размер полосы зависит от вашего процессора, но вы можете поэкспериментировать с ним (или начать с того же объема данных, который использовался для чтения во внутреннем цикле, если он достаточно большой).
Например:
stripe_number = 0;
do
{
count = fread(striped_buffer+(STRIPE_SIZE*stripe_number*NUM_IMAGES), 1, STRIPE_SIZE, image_file);
stripe_number++;
} while(count != 0);
Читайте по одному файлу за раз, чтобы не искать на своем диске туда-сюда.
Независимо от того, чтобы максимизировать производительность, вы, вероятно, захотите использовать асинхронный / перекрывающийся ввод-вывод дляваш следующий бит данных изображения будет поступать в то время, когда вы обрабатываете предыдущий бит.
Если вы разрабатываете под Windows, это может дать вам начало выполнения перекрывающегося ввода-вывода: http://msdn.microsoft.com/en-us/library/ms686358%28v=vs.85%29.aspx
Как только вы выполняете свой ввод-вывод параллельно, вы можете выяснить, находится ли ваше узкое место во вводе-выводе или в обработке.Существуют разные методы их оптимизации.