Авто векторизация Область интереса (урожай)

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

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 является вершиной области интереса

1

Решение

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

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

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

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

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

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

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

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

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

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector