2012-09-18 2 views
1

У меня есть библиотека, которая имеет некоторые алгоритмы обработки изображений, включая алгоритм Region of Interest (crop). При компиляции с GCC автоматический векторный указатель ускоряет выполнение большого количества кода, но ухудшает производительность алгоритма Crop. Есть ли способ помечать определенный цикл для игнорирования векторизатором или есть лучший способ структурирования кода для лучшей производительности?Автоматическая векторная география Область интереса (культура)

for (RowIndex=0;RowIndex<Destination.GetRows();++RowIndex) 
{ 
    rowOffsetS = ((OriginY + RowIndex) * SizeX) + OriginX; 
    rowOffsetD = (RowIndex * Destination.GetColumns()); 
    for (ColumnIndex=0;ColumnIndex<Destination.GetColumns();++ColumnIndex) 
    { 
     BufferSPtr=BufferS + rowOffsetS + ColumnIndex; 
     BufferDPtr=BufferD + rowOffsetD + ColumnIndex; 
     *BufferDPtr=*BufferSPtr; 
    } 
} 

Где SizeX ширина источника OriginX является левой области интереса OriginY является вершиной области интереса

+0

Я не уверен, что правильно задал вопрос. Вы хотите либо обозначить этот цикл, чтобы он не был векторизован, либо реструктурировал его для лучшей производительности? Кажется, это противоречие. Но что касается производительности: могут ли два диапазона перекрываться? Если нет: вы используете '__restrict' на указателе, чтобы сделать это ясным для компилятора? Pointeraliasing - большой демонстратор для оптимизации. Кроме того: подумали ли вы об использовании 'std :: copy' для вашего внутреннего цикла? Это может быть лучше оптимизировано и сделает ваш код короче. – Grizzly

+0

Это похоже на противоречие, но это идея. Векторизация в настоящее время ухудшает производительность, поэтому либо отключить ее для этого цикла, либо улучшить код - это два варианта, о которых я мог подумать! Я дам ограничить и скопировать. – illumi

+0

Возможно, вы захотите упомянуть, что производительность для урожая в этом случае ухудшается в вашем вопросе. В его основе я предполагал, что выполнение алгоритма Crop остается неизменным при векторизации.Если вы еще этого не знаете, флаг '-ftree-vectorizer-verbose = n' может помочь вам получить более конкретную информацию о том, что делает оптимизатор и почему. – Grizzly

ответ

0

Я не нашел ничего об изменении оптимизации флаги для цикла, однако в соответствии с документацией вы можете использовать атрибут optimize (посмотрите here и here) на функцию, чтобы переопределить параметры оптимизации для этой функции примерно так:

void foo() __attribute__((optimize("O2", "inline-functions"))) 

Если вы хотите изменить его для нескольких функций, вы можете использовать #pragma GCC optimize установить его для всех следующих функций (look here).

Таким образом, вы должны скомпилировать функцию, содержащую растение, с другим набором флагов оптимизации, опустив автоинъекцию. Это имеет недостаток жесткого кодирования флагов компиляции для этой функции, но это лучшее, что я нашел.

Что касается реструктуризации для повышения производительности двух точек я уже упоминал в комментариях приходят на ум (если предположить, что диапазоны не могут пересекаться):

  • декларирующую указатели, как __restrict сказать компилятору, что они не являются псевдонимами (область, на которую указывает один указатель, не будет доступна никакими другими средствами внутри функции). Возможность сглаживания указателей является основным камнем преткновения для оптимизатора, поскольку он не может легко изменить порядок доступа, если он не знает, изменит ли запись на BufferD содержимое BufferS.

  • Замена внутреннего цикла с вызовом для копирования:

    std::copy(BufferS + rowOffsetS, BufferS + rowOffsetS + Destination.GetColumns(), BufferD + rowOffsetD); 
    

    copy функция, вероятно, будет довольно хорошо оптимизировано (вероятно, пересылка аргументов memmove), так что может сделать ваш код быстрее, в то время как также делая ваш код короче (всегда плюс).

+0

Использование копии отключает автоматическую векторию этого цикла ** и ** обеспечивает немного лучшую производительность по сравнению с тем, что у меня было раньше. Благодаря! – illumi