के संबंध में जीसीसी व्यवहार को परेशान करना प्रारंभ में #pragma omp simd
निर्देश के प्रभाव की जांच कर रहा है, मैं एक ऐसे व्यवहार में आया जो मैं व्याख्या नहीं कर सकता, लूप के लिए सरल के वेक्टरलाइजेशन से संबंधित। निम्नलिखित कोड नमूना का परीक्षण इस भयानक compiler explorer पर किया जा सकता है, बशर्ते -O3 निर्देश लागू किया गया है और हम x86 आर्किटेक्चर पर हैं।वेक्टरनाइज़ेशन और लूप आकार
क्या कोई मुझे निम्नलिखित अवलोकनों के पीछे तर्क समझा सकता है?
#include <stdint.h>
void test(uint8_t* out, uint8_t const* in, uint32_t length)
{
unsigned const l1 = (length * 32)/32; // This is vectorized
unsigned const l2 = (length/32)*32; // This is not vectorized
unsigned const l3 = (length << 5)>>5; // This is vectorized
unsigned const l4 = (length >> 5)<<5; // This is not vectorized
unsigned const l5 = length -length%32; // This is not vectorized
unsigned const l6 = length & ~(32 -1); // This is not vectorized
for (unsigned i = 0; i<l1 /*pick your choice*/; ++i)
{
out[i] = in[i*2];
}
}
मुझे क्या पहेली है कि दोनों एल 1 और एल 3 beeing 32. के गुणकों और लेंथ नहीं vectorized कोड का उत्पादन करते हैं सब के सब होने की गारंटी नहीं के बावजूद vectorized कोड उत्पन्न है, लेकिन 32 के गुणकों होना चाहिए क्या इसके पीछे कोई कारण है?
एक तरफ, #pragma omp simd निर्देश का उपयोग वास्तव में कुछ भी नहीं बदलता है।
संपादित करें: आगे की जांच पड़ताल करने के बाद, व्यवहार के अंतर गायब हो जाता है जब सूचकांक प्रकार size_t है (और कोई सीमा हेरफेर भी जरूरत है), जिसका अर्थ है कि इस vectorized कोड उत्पन्न करता है: अगर किसी को पता है क्यों
#include <stdint.h>
#include <string>
void test(uint8_t* out, uint8_t const* in, size_t length)
{
for (size_t i = 0; i<length; ++i)
{
out[i] = in[i*2];
}
}
लूप वेक्टरिंग इंडेक्स प्रकार पर इतना निर्भर है, तो मुझे और जानना उत्सुक होगा!
EDIT2, मार्क Lakata करने के लिए धन्यवाद, ओ 3 वास्तव में जरूरत है
इस प्रश्न के विस्तार के रूप में क्या देखा जा सकता है, सटीक वही व्यवहार क्लैंग के साथ दिखाई देता है, इसलिए मुझे लगता है कि इसमें कुछ तर्क है। –
ऐसा लगता है कि संकलक डरता है कि सूचकांक लपेट सकता है और इसके कारण छोड़ देता है :-( –
प्रकार निर्भरता मुझे समझाया गया है, ओवरफ्लो के जोखिम से जुड़ा हुआ है (जो वेक्टरेशन को रोकता है)। एक हस्ताक्षरित ओवरफ्लो की अनुमति है , जबकि एक हस्ताक्षरित ओवरफ्लो नहीं है, जो इस आखिरी बिंदु को बताता है। पहले हस्ताक्षर का उपयोग करना और प्रभावी रूप से अतिप्रवाह जोखिम को मारना) वेक्टरेशन के लिए अनुमति देता है, जीसीसी सुपर स्मार्ट है: https://godbolt.org/g/SsVZ2r –