2017-01-27 8 views
1

Я запускаю фильтр на изображении, и я выполняю вертикальный проход, за которым следует горизонтальный проход. Функция для этой задачи одинакова для обоих проходов, меняются только значения аргументов. Я вызываю функцию в цикле. Для векторизации операций в этой функции я должен написать отдельные вызовы функций для двух проходов. Теперь петля разделена на горизонтальные и вертикальные проходы. Из-за этого изменения добавлено «если условие», и я заметил, что даже если вычисления векторизованы, ядро ​​занимает больше времени для выполнения. Я запустил код несколько раз, и среднее время, затраченное на векторизованный код, больше, чем исходный код. Это из-за того, что «если условие» включено в код?Действительно ли «если условия» влияют на производительность выполнения ядра в OpenCL?

Оригинальный код

global int* a; 

for(int i = 0; i < 4; i++) 
{ 
    filter(a + i, b, c); 
} 

Модифицированный код

global int* a; 

if(offset == 1) 
for(int i = 0; i < 4; i++) 
{ 
    filter_vertical(a + i, b, c); 
} 
else 
    filter_horizontal(a, b, c); 
+0

Пожалуйста, покажите нам фрагмент вашего фрагмента кода. Способ использования выражения 'if' может изменить ответ. –

ответ

1

вы имели в виду offset == 1?

if(offset = 1) 

присваивает 1 смещение, которое является «дополнительной задержкой» для каждой нити. Это медленнее оригинала. Но кроме этого, «если» изменяет производительность вверх или вниз в зависимости от структуры «взятой» или «не взятой» ветки, сгруппированной вместе, поскольку некоторые архитектуры, такие как GPU SIMD, заполняют пузырьки для параллельных конвейеров SIMD, если они не являются одинаковыми параметрами ветвления с соседним конвейером, чтобы они оставались на других возможностях использования потоков волнового фронта, если они не могут заполнить нитер, он будет иметь меньшую производительность.

Для большей производительности,

for(int i = 0; i < 4; i++) 
{ 
    filter_vertical(a + i, b, c); 
} 

в

filter_vertical(a , b, c); 
    filter_vertical(a + 1, b, c); 
    filter_vertical(a + 2, b, c); 
    filter_vertical(a + 3, b, c); 

нуждается в большем количестве кэша команд, но требует меньше ветвей, требует меньше использования памяти и меньше циклов.

Если вы можете группировать смещение == 1 вместе, это было бы быстрее, если операции доступа к памяти не повлияют на него.