Bu soru, gcc (4.6.3 Ubuntu) ve SSE intrinsics için açılma döngülerindeki davranışı ile hemen işlenenlerle ilgilidir.Ne gcc seçeneği, SSE intrinsics için anında işlenenlerle döngü açmayı sağlar?
Anında işlenen bir içsel örnek, _mm_blend_ps'dir. Yalnızca sabit olabilen 4 bitlik bir tamsayıyı bekler. Bununla birlikte, -O3 seçeneğini kullanarak, derleyici görünür şekilde döngüleri otomatik olarak açar (döngü sayacı değerleri derleme zamanında belirlenebilirse) ve farklı anlık değerlerle karşılık gelen karışım komutunun birden çok örneğini üretir.
Bu harmanın hemen işlenen 16 olası değerler arasında çalışan basit bir test kodu (blendsimple.c) aşağıdaki gibidir: mümkündür
#include <stdio.h>
#include <x86intrin.h>
#define PRINT(V) \
printf("%s: ", #V); \
for (i = 3; i >= 0; i--) printf("%3g ", V[i]); \
printf("\n");
int
main()
{
__m128 a = _mm_set_ps(1, 2, 3, 4);
__m128 b = _mm_set_ps(5, 6, 7, 8);
int i;
PRINT(a);
PRINT(b);
unsigned mask;
__m128 r;
for (mask = 0; mask < 16; mask++) {
r = _mm_blend_ps(a, b, mask);
PRINT(r);
}
return 0;
}
bu kod derleme
gcc -Wall -march=native -O3 -o blendsimple blendsimple.c
ve kod çalışır. Açıkçası, derleyici döngüyü kaydırarak hemen işlenen için sabitler ekler.
Ancak,
gcc -Wall -march=native -O2 -o blendsimple blendsimple.c
Eğer içsel harmanı için aşağıdaki hatayı alıyorum
ile kod derleme ise:
error: the last argument must be a 4-bit immediate
Şimdi belirli derleyici bayrağı aktif olduğunu öğrenmek için çalıştı - O3 ancak -O2'de olmayan, derleyicinin döngüyü açmasına izin vermedi, ancak başarısız oldu.
gcc -c -Q -O3 --help=optimizers > /tmp/O3-opts
gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts
diff /tmp/O2-opts /tmp/O3-opts | grep enabled
-o2 tarafından -o3 değil tarafından etkinleştirilen tüm seçenekleri listelenmektedir:
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Overall-Options.html
gcc çevrimiçi dokümanlardan ardından aşağıdaki komutları yürütür. Ben
gcc -Wall -march=native -O2 -fgcse-after-reload -finline-functions -fipa-cp-clone -fpredictive-commoning -ftree-loop-distribute-patterns -ftree-vectorize -funswitch-loops blendsimple blendsimple.c
-o2 ek olarak 7 sıralanan bayrakların tüm eklediğinizde ı davranış tam -o3 ile aynı olduğunu beklenebilir. Ancak derleyici, "son argümanın derhal 4-bit olması gerektiği" konusunda şikayet ediyor.
Sorunun ne olduğu hakkında bir fikri olan var mı? Bu döngü döngüsünü etkinleştirmek için hangi bayrağın gerekli olduğunu bilmek iyi olur. Bu sayede #pragma GCC optimizasyonu veya bir işlev özelliği kullanılarak seçici olarak etkinleştirilebilir.
(Ayrıca, -O3'ün açma-döngüler seçeneğinin bile etkin olmadığını bile bilmiyorum).
Herhangi bir yardım için minnettar olurum. Bu, verdiğim SSE programlama üzerine bir konferans.
Düzenleme: Yorumlarınız için çok teşekkürler. jtaylor haklı görünüyor. Elimi iki yeni gcc (4.7.3, 4.8.2) sürümüne aldım ve 4.8.2 optimizasyon seviyesinden bağımsız olarak derhal problemden şikayet ediyor. Moverover, daha sonra gcc 4.6.3 kodu -O2 -funroll-döngülerle derlediğini fark ettim, fakat bu da 4.8.2'de başarısız oluyor. Görünüşe göre, bu özelliğe güvenilemez ve Jason R'nin belirttiği gibi, cpp veya şablonlar kullanılarak her zaman "manuel" olarak açılmalıdır.
4-bit bile -o3 ile immediate' . –
Açılış işlemini her zaman önişlemci hilesi veya şablon meta programlaması (C++ ile yazıyorsanız) kullanarak elle uygulayabilirsiniz. –
Bu davranış derleyici hataları (4.8'de giderilmiştir) gibi görünüyor. Derleyicilerin farklı optimizasyon düzeylerinde hatalar vermemesi gerekiyor. gcc, her zaman anlık olmayanları (örneğin şartlı olarak) desteklemeli veya asla desteklememelidir. Daha sonraki sürümlerinde daha sonra seçtikleri görünüyor. Hangi mantıklı, içsel makine talimatları etrafında çok ince sarmalayıcılar olması gerekiyordu – jtaylor