Tôi gặp sự cố với phương pháp SSE mà tôi đang viết thực hiện xử lý âm thanh. Tôi đã thực hiện một chức năng ngẫu nhiên SSE dựa trên giấy của Intel ở đây:SSE nội tại gây ra hoạt động nổi bình thường để trả về -1. # INV
Tôi cũng có một phương pháp mà đang thực hiện chuyển đổi từ phao để S16 sử dụng SSE cũng có, việc chuyển đổi được thực hiện khá đơn giản như sau:
unsigned int Float_S16LE(float *data, const unsigned int samples, uint8_t *dest)
{
int16_t *dst = (int16_t*)dest;
const __m128 mul = _mm_set_ps1((float)INT16_MAX);
__m128 rand;
const uint32_t even = count & ~0x3;
for(uint32_t i = 0; i < even; i += 4, data += 4, dst += 4)
{
/* random round to dither */
FloatRand4(-0.5f, 0.5f, NULL, &rand);
__m128 rmul = _mm_add_ps(mul, rand);
__m128 in = _mm_mul_ps(_mm_load_ps(data),rmul);
__m64 con = _mm_cvtps_pi16(in);
memcpy(dst, &con, sizeof(int16_t) * 4);
}
}
FloatRand4 được định nghĩa như sau:
static inline void FloatRand4(const float min, const float max, float result[4], __m128 *sseresult = NULL)
{
const float delta = (max - min)/2.0f;
const float factor = delta/(float)INT32_MAX;
...
}
Nếu sseresult != NULL
cácKết quảđược trả về và result
không được sử dụng. Điều này thực hiện hoàn hảo trên vòng đầu tiên, nhưng trên vòng lặp tiếp theo delta
trở thành -1.#INF
thay vì 1.0
. Nếu tôi nhận xét ra dòng __m64 con = _mm_cvtps_pi16(in);
sự cố sẽ biến mất.
Tôi nghĩ rằng FPU đang đi vào trạng thái không xác định hoặc điều gì đó.
_mm_cvtps_pi16 là một ý tưởng tồi. Sử dụng kết hợp _mm_cvtps_epi32, _mm_packs_epi32 và _mm_store_si128/_mm_storeu_si128 để chuyển đổi 8 float thành 8 int16_t và sự cố của bạn đã biến mất! –