Самый эффективный способ преобразовать вектор с плавающей запятой в вектор uint32?

Это дополнительный вопрос к этому один. Теперь я хотел бы преобразовать в обратном направлении float -> unsigned int. Какова оптимальная и точная векторная последовательность следующей скалярной операции?

float x = ...
unsigned int res = (unsigned int)x;

person zr.    schedule 06.02.2012    source источник
comment
stackoverflow.com/questions/78619/   -  person Anycorn    schedule 06.02.2012
comment
Не тот же вопрос! Я хочу преобразовать в unsigned int   -  person zr.    schedule 06.02.2012
comment
что ты хочешь делать со знаком минус?   -  person Anycorn    schedule 06.02.2012
comment
Что вы имеете в виду под векторной последовательностью? sse на x86? Внутренние?   -  person Gunther Piez    schedule 06.02.2012
comment
либо sse assembly, либо sse intrinsics подойдут   -  person zr.    schedule 06.02.2012


Ответы (1)


Это основано на примере из старой, но полезной документации по миграции Apple AltiVec-SSE, которая, к сожалению, больше не доступна по адресу http://developer.apple.com:

inline __m128i _mm_ctu_ps(const __m128 f)
{
    const __m128 two31 = _mm_set1_ps(0x1.0p31f);
    const __m128 two32 = _mm_add_ps(two31, two31);
    const __m128 zero = _mm_xor_ps(f,f);

    // check for overflow before conversion to int
    const __m128 overflow = _mm_cmpge_ps(f, two31);
    const __m128 overflow2 = _mm_cmpge_ps(f, two32);
    const __m128 subval = _mm_and_ps(overflow, two31);
    const __m128i addval = _mm_slli_epi32((__m128i)overflow, 31);
    __m128i result;

    // bias the value to signed space if it is >= 2**31
    f = _mm_sub_ps(f, subval);

    // clip at zero
    f = _mm_max_ps(f, zero);

    // convert to int with saturation
    result = _mm_cvtps_epi32(f); // rounding mode should be round to nearest

    // unbias
    result = _mm_add_epi32(result, addval);

    // patch up the overflow case
    result = _mm_or_si128(result, (__m128i)overflow2);

    return result;
}
person Paul R    schedule 06.02.2012