Trying to improve and better understand Intel SSE intrinsics I've been writing a collection of signal processing function optimized with SSE intrinsics (mostly for audio processing). Here is a linear interpolation function I wrote. It works well and is quite fast (much better than straight lerp), but I'm using the full 8 registers available, and I'm wondering if there's something I'm not seeing that would improve its efficiency.

void SSE_vInterpLinear (const float *sourceX, const float *sourceY, float *resultY, const int lengthX)
{
    assert(lengthX % 4 == 0);

    __m128 *mXphases = (__m128*)sourceX;
    __m128 *mYresult = (__m128*)resultY;
    __m128 mX0, mY0, mY1, mYtemp, mXtemp, mtemp;
    __declspec(align(16)) float pos[4];

    for (int i = 0; i &lt; lengthX; i+=4) {
        // floor the values in X to get indexing positions at X0, and add 1 for X1 index positions
        mX0 = _mm_floor_ps(*mXphases);
        _mm_store_ps(pos, mX0);
        mY0 = _mm_set_ps(sourceY[(int)pos[3]], sourceY[(int)pos[2]], sourceY[(int)pos[1]], sourceY[(int)pos[0]]);
        mY1 = _mm_set_ps(sourceY[(int)pos[3]+1], sourceY[(int)pos[2]+1], sourceY[(int)pos[1]+1], sourceY[(int)pos[0]+1]);

        mYtemp = _mm_sub_ps(mY1, mY0);
        mXtemp = _mm_sub_ps(*mXphases, mX0);
        mtemp = _mm_mul_ps(mYtemp, mXtemp);
        *mYresult = _mm_add_ps(mY0, mtemp);

        mXphases++;
        mYresult++;
    }
}
One improvement would be to restrict the number of (random) memory accesses. First notice is that for each sourceY[fixed] there's also a memory read from sourceY[fixed+1];

I believe these should be at least combined to single 64-bit memory accesses.

A more crucial improvement would be at higher level: is the interpolation really random, or could the xvalues be say localized to say 8-15 successive indices? Then I'd pursuit for a technique that reads them to 2 or 4 xmm registers and tries to shuffle the values in place an in parallel.