का उपयोग करने के बाद धीमा चलता है मुझे कुछ एसएसई 2 और एवीएक्स कोड के साथ एक अजीब समस्या है जो मैं काम कर रहा हूं। मैं जीसीसी का उपयोग कर अपना आवेदन बना रहा हूं जो रनटाइम सीपीयू फीचर डिटेक्शन। वस्तु फ़ाइलों, प्रत्येक सीपीयू सुविधा के लिए अलग झंडों से निर्माण कर रहे हैं, उदाहरण के लिए:एसईएस AVX
g++ -c -o ConvertSamples_SSE.o ConvertSamples_SSE.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -msse
g++ -c -o ConvertSamples_SSE2.o ConvertSamples_SSE2.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -msse2
g++ -c -o ConvertSamples_AVX.o ConvertSamples_AVX.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -mavx
जब मैं पहली बार कार्यक्रम शुरू, मुझे लगता है कि SSE2 दिनचर्या गैर SSE दिनचर्या पर एक अच्छा गति को बढ़ावा देने के साथ सामान्य के अनुसार हैं (लगभग 100% तेज)। किसी भी एवीएक्स दिनचर्या को चलाने के बाद, सटीक वही एसएसई 2 दिनचर्या अब बहुत धीमी गति से चलती है।
क्या कोई यह बता सकता है कि इसका क्या कारण हो सकता है?
एवीएक्स दिनचर्या से पहले, सभी परीक्षण 80-130% तेज होते हैं तो एफपीयू गणित, जैसा कि यहां देखा जा सकता है, एवीएक्स दिनचर्या के बाद, एसएसई दिनचर्या बहुत धीमी होती है।
यदि मैं एवीएक्स परीक्षण दिनचर्या छोड़ देता हूं तो मुझे यह प्रदर्शन हानि कभी नहीं दिखाई देती है।
यहाँ मेरी SSE2 दिनचर्या
void Float_S16(const float *in, int16_t *out, const unsigned int samples)
{
static float ratio = (float)Limits<int16_t>::range()/(float)Limits<float>::range();
static __m128 mul = _mm_set_ps1(ratio);
unsigned int i;
for (i = 0; i < samples - 3; i += 4, in += 4, out += 4)
{
__m128i con = _mm_cvtps_epi32(_mm_mul_ps(_mm_load_ps(in), mul));
out[0] = ((int16_t*)&con)[0];
out[1] = ((int16_t*)&con)[2];
out[2] = ((int16_t*)&con)[4];
out[3] = ((int16_t*)&con)[6];
}
for (; i < samples; ++i, ++in, ++out)
*out = (int16_t)lrint(*in * ratio);
}
और उसी के avx संस्करण है।
void Float_S16(const float *in, int16_t *out, const unsigned int samples)
{
static float ratio = (float)Limits<int16_t>::range()/(float)Limits<float>::range();
static __m256 mul = _mm256_set1_ps(ratio);
unsigned int i;
for (i = 0; i < samples - 7; i += 8, in += 8, out += 8)
{
__m256i con = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_load_ps(in), mul));
out[0] = ((int16_t*)&con)[0];
out[1] = ((int16_t*)&con)[2];
out[2] = ((int16_t*)&con)[4];
out[3] = ((int16_t*)&con)[6];
out[4] = ((int16_t*)&con)[8];
out[5] = ((int16_t*)&con)[10];
out[6] = ((int16_t*)&con)[12];
out[7] = ((int16_t*)&con)[14];
}
for(; i < samples; ++i, ++in, ++out)
*out = (int16_t)lrint(*in * ratio);
}
मैंने इसे वालग्रिंड के माध्यम से भी चलाया है जो कोई त्रुटि नहीं पहचानता है।
समय कैसे मापा जाता है अन्य बदलाव केवल 1 चक्र कर रहे हैं? – Gilles
@ घड़ी 'घड़ी_gettime (CLOCK_MONOTONIC, और प्रारंभ) का उपयोग करके;' पहले और बाद में, फिर अंतर की गणना। – Geoffrey
मैंने मिश्रित एसएसईएक्स और एवीएक्स कोड के साथ उत्सुक समस्याओं में भाग लिया है ..., ज्यादातर क्योंकि लिंक टाइम कोड पीढ़ी/आदि। समस्या का। अपनी असेंबली फ़ाइलों को देखो (और शायद पोस्ट)। – Christopher