Robię trochę przetwarzania obrazu, z którego czerpię korzyści z wektoryzacji. Mam funkcję, która wektoryzuje ok, ale dla których nie jestem w stanie przekonać kompilator, że bufor wejściowy i wyjściowy nie nakładają się, więc nie jest konieczne sprawdzanie aliasów. Powinienem móc to zrobić, używając __restrict__
, ale jeśli bufory nie są zdefiniowane jako __restrict__
po pojawieniu się jako argument funkcji, nie ma sposobu, aby przekonać kompilator, że jestem absolutnie pewny, że 2 bufory nigdy się nie pokrywają.Automatyczne wektoryzacja: Przekonanie kompilatora, że sprawdzanie aliasu nie jest konieczne
to funkcja:
__attribute__((optimize("tree-vectorize","tree-vectorizer-verbose=6")))
void threshold(const cv::Mat& inputRoi, cv::Mat& outputRoi, const unsigned char th) {
const int height = inputRoi.rows;
const int width = inputRoi.cols;
for (int j = 0; j < height; j++) {
const uint8_t* __restrict in = (const uint8_t* __restrict) inputRoi.ptr(j);
uint8_t* __restrict out = (uint8_t* __restrict) outputRoi.ptr(j);
for (int i = 0; i < width; i++) {
out[i] = (in[i] < valueTh) ? 255 : 0;
}
}
}
Jedyny sposób można przekonać kompilator aby nie wykonywać sprawdzenie alias czy umieścić wewnętrzną pętlę odrębną funkcję, w której wskaźniki są określane jako __restrict__
argumenty. Jeśli zadeklaruję tę wewnętrzną funkcję jako wstawioną, ponownie włącza się sprawdzanie aliasu.
można zobaczyć efekt także z tego przykładu, który moim zdaniem jest zgodna: http://goo.gl/7HK5p7
(Uwaga: wiem, że mogłyby być lepsze sposoby pisania tę samą funkcję, ale w tym przypadku jestem po prostu staramy się dowiedz się, jak uniknąć aliasu)
Edytuj:
Problem został rozwiązany !! (Patrz answer below)
Korzystanie z gcc 4.9.2, here is the complete example. Zauważ użycie flagi kompilatora -fopt-info-vec-optimized
zamiast zastąpionej -ftree-vectorizer-verbose=N
.
Tak więc, dla gcc, użyj #pragma GCC ivdep
i ciesz się! :)
Pamiętaj, że problem z wpisaniem może zostać naprawiony dla gcc-5: https://gcc.gnu.org/ml/gcc-patches/2014-09/msg00606.html –
Dziękujemy za wyświetlenie kompilatora WWW w wersji C++ – StarShine
nie mam już gotowej kopii openCV do przetestowania, ale może uda ci się przekonać kompilator, że 'inputRoi' i' outputRoi' odwołują się do różnych buforów za pomocą instrukcji '__assume (in! = out)'? Jest dużo rzeczy, które można zrobić z '__assume', ale to zależy w dużej mierze od tego, czy kompilator jest wystarczająco inteligentny, aby to zrozumieć. – Stefan