Я пытаюсь использовать Intel Intrinsics для быстрой работы с массивом float
. Кажется, что эти операции работают нормально; однако, когда я пытаюсь получить результат операции в стандартную переменную C, я получаю SEGFAULT. Если я прокомментирую указанную строку ниже, программа запустится. Если я сохраню результат указанной строки, но никак не буду манипулировать ею, программа будет работать нормально. Только когда я пытаюсь (каким-либо образом) взаимодействовать с результатом _mm_cvtss_f32(C)
, что моя программа вылетает. Есть идеи?SSE SIMD Сегментация Неисправность при использовании результирующего float
float proc(float *a, float *b, int n, int c, int width) {
// Operation: SUM: (A - B)^2
__m128 A, B, C;
float total = 0;
for (int d = 0, k = 0; k < c; d += width, k++) {
for (int i = 0; i < n/4 * 4; i += 4) {
A = _mm_load_ps(&a[i + d]);
B = _mm_load_ps(&b[i + d]);
C = _mm_sub_ps(A, B);
C = _mm_mul_ps(C, C);
C = _mm_hadd_ps(C, C);
C = _mm_hadd_ps(C, C);
total += _mm_cvtss_f32(C); // SEGFAULT HERE
}
for (int i = n/4 * 4; i < n; i++) {
int diff = a[i + d] - b[i + d];
total += diff * diff;
}
}
return total;
}
Вы действительно уверены, что ваша программа действительно вылетает из инструкции, которую вы указали, или компилятор просто оптимизирует остальную часть цикла, если вы удалите строку '_mm_cvtss_f32()' (у нее нет других видимых побочных эффектов) ? Потенциальными причинами отказа были бы неправильное выравнивание массивов 'a' и' b', поскольку вы используете согласованные инструкции загрузки. Вы уверены, что они выровнены по 16 байт? На современном оборудовании Intel очень мало разницы в производительности между 16-байтовыми выровненными и невыровненными нагрузками («movaps» имеет более короткую командную кодировку, чем «movups», но это о ней). –
Спасибо, я изменил 'load' на' loadu', и теперь он работает! – Simon
@JasonR: Их кодировка имеет одинаковую длину. http://www.felixcloutier.com/x86/MOVAPS.html против http://www.felixcloutier.com/x86/MOVUPS.html. Если вы сравнивали разборку, у одного из них был префикс REX или другой режим адресации? Во всяком случае, они выполняются идентично, когда данные выравниваются во время выполнения, но когда пропускная способность чтения кэша L1 является узким местом, выровненные нагрузки имеют преимущество. Это хорошая идея, чтобы ваши данные были выровнены, когда это было дешево. –