HexEdit/Misc.cpp
size_t FindFirstDiff(const unsigned char * buf1, const unsigned char * buf2, size_t buflen)
{
	assert((int)buf1 % SZCHK == (int)buf2 % SZCHK);         // ensure same memory alignment

	// Work out where to start the SSE2 compare by rounding up to next 16-byte memory chunk
	__m128i * pchunk1 = (__m128i *)((((int)buf1 + SZCHK-1)/SZCHK)*SZCHK);
	assert((int)pchunk1 % SZCHK == 0);

	const unsigned char * p1, * p2;
	const unsigned char * pend = (const unsigned char *)pchunk1;
	if (pend > buf1 + buflen)
		pend = buf1 + buflen;

	// Check up to 15 bytes before the first 16-byte aligned chunk
	for (p1 = buf1, p2 = buf2; p1 < pend; ++p1, ++p2)
	{
		if (*p1 != *p2)
			return p1 - buf1;
	}

	__m128i * pchunk2 = (__m128i *)((((int)buf2 + SZCHK-1)/SZCHK)*SZCHK);
	assert((int)pchunk2 % SZCHK == 0);

	pend = buf1 + buflen;

	__m128i cmp;                                                // holds result of comparing 16 bytes where each DWORD is either all bits on or off

	for ( ; (const unsigned char *)pchunk1 < pend - SZCHK; ++pchunk1, ++pchunk2)
	{
		cmp = _mm_cmpeq_epi32(*pchunk1, *pchunk2);              // PCMPEQD
		if (_mm_movemask_ps(_mm_castsi128_ps(cmp)) != 0xF)      // MOVMSKPS
		{
			// There is at least one difference in the 16 bytes - find the first diff. byte
			for (p1 = (const unsigned char *)pchunk1, p2 = (const unsigned char *)pchunk2; *p1 == *p2; ++p1, ++p2)
			{
				; // nothing required in the loop body
			}
			assert(p1 - (const unsigned char *)pchunk1 < SZCHK); // else we have done something wrong (or PCMPEQD did not work)
			return p1 - buf1;
		}
	}

	// Check up to 15 bytes past the last 16-byte aligned chunk
	for (p1 = (const unsigned char *)pchunk1, p2 = (const unsigned char *)pchunk2; p1 < pend; ++p1, ++p2)
	{
		if (*p1 != *p2)
			return p1 - buf1;
	}

	return buflen;
}
// FindFirstDiff:
//    Quickly find the first byte that is different in two buffers.
//
// Parameters:
//    buf1, buf2 = the buffers to compare
//    buflen = how far to look
//
// Notes:
//    IMPORTANT - buf1, and buf2 must have the same 16-byte alignment, though the actual
//    first byte does not have to be on a 16-byte boundary (ie: buf1%16 == buf2%16).
//
// Return value:
//    The number of bytes up to the first difference OR
//    buflen if both buffers are the same

Quickly find the first byte that is different in two buffers.

buf1, buf2 = the buffers to compare
buflen = how far to look

buf1, and buf2 must have the same 16-byte alignment, though the actual
first byte does not have to be on a 16-byte boundary .

Return value:
The number of bytes up to the first difference OR
buflen if both buffers are the same
Quickly find the first byte that is different in two buffers . buf1 buf2 = the buffers to compare buflen = how far to look buf1 and buf2 must have the same 16 - byte alignment though the actual first byte does not have to be on a 16 - byte boundary . Return value : The number of bytes up to the first difference OR buflen if both buffers are the same
size_t FindFirstDiff(const unsigned char * buf1, const unsigned char * buf2, size_t buflen)
{
	assert((int)buf1 % SZCHK == (int)buf2 % SZCHK);         
	__m128i * pchunk1 = (__m128i *)((((int)buf1 + SZCHK-1)/SZCHK)*SZCHK);
	assert((int)pchunk1 % SZCHK == 0);
	const unsigned char * p1, * p2;
	const unsigned char * pend = (const unsigned char *)pchunk1;
	if (pend > buf1 + buflen)
		pend = buf1 + buflen;
	for (p1 = buf1, p2 = buf2; p1 < pend; ++p1, ++p2)
	{
		if (*p1 != *p2)
			return p1 - buf1;
	}
	__m128i * pchunk2 = (__m128i *)((((int)buf2 + SZCHK-1)/SZCHK)*SZCHK);
	assert((int)pchunk2 % SZCHK == 0);
	pend = buf1 + buflen;
	__m128i cmp;                                                
	for ( ; (const unsigned char *)pchunk1 < pend - SZCHK; ++pchunk1, ++pchunk2)
	{
		cmp = _mm_cmpeq_epi32(*pchunk1, *pchunk2);              
		if (_mm_movemask_ps(_mm_castsi128_ps(cmp)) != 0xF)      
		{
			for (p1 = (const unsigned char *)pchunk1, p2 = (const unsigned char *)pchunk2; *p1 == *p2; ++p1, ++p2)
			{
				; 
			}
			assert(p1 - (const unsigned char *)pchunk1 < SZCHK); 
			return p1 - buf1;
		}
	}
	for (p1 = (const unsigned char *)pchunk1, p2 = (const unsigned char *)pchunk2; p1 < pend; ++p1, ++p2)
	{
		if (*p1 != *p2)
			return p1 - buf1;
	}
	return buflen;
}
size_t FindFirstDiff ( const unsigned char * buf1 , const unsigned char * buf2 , size_t buflen ) { assert ( ( int ) buf1 % SZCHK == ( int ) buf2 % SZCHK ) ; __m128i * pchunk1 = ( __m128i * ) ( ( ( ( int ) buf1 + SZCHK - 1 ) / SZCHK ) * SZCHK ) ; assert ( ( int ) pchunk1 % SZCHK == 0 ) ; const unsigned char * p1 , * p2 ; const unsigned char * pend = ( const unsigned char * ) pchunk1 ; if ( pend > buf1 + buflen ) pend = buf1 + buflen ; for ( p1 = buf1 , p2 = buf2 ; p1 < pend ; ++ p1 , ++ p2 ) { if ( * p1 != * p2 ) return p1 - buf1 ; } __m128i * pchunk2 = ( __m128i * ) ( ( ( ( int ) buf2 + SZCHK - 1 ) / SZCHK ) * SZCHK ) ; assert ( ( int ) pchunk2 % SZCHK == 0 ) ; pend = buf1 + buflen ; __m128i cmp ; for ( ; ( const unsigned char * ) pchunk1 < pend - SZCHK ; ++ pchunk1 , ++ pchunk2 ) { cmp = _mm_cmpeq_epi32 ( * pchunk1 , * pchunk2 ) ; if ( _mm_movemask_ps ( _mm_castsi128_ps ( cmp ) ) != 0xF ) { for ( p1 = ( const unsigned char * ) pchunk1 , p2 = ( const unsigned char * ) pchunk2 ; * p1 == * p2 ; ++ p1 , ++ p2 ) { ; } assert ( p1 - ( const unsigned char * ) pchunk1 < SZCHK ) ; return p1 - buf1 ; } } for ( p1 = ( const unsigned char * ) pchunk1 , p2 = ( const unsigned char * ) pchunk2 ; p1 < pend ; ++ p1 , ++ p2 ) { if ( * p1 != * p2 ) return p1 - buf1 ; } return buflen ; }
FindFirstDiff:
Quickly find the first byte that is different in two buffers.
FindFirstDiff : Quickly find the first byte that is different in two buffers .
// ensure same memory alignment
 // Work out where to start the SSE2 compare by rounding up to next 16-byte memory chunk
 // Check up to 15 bytes before the first 16-byte aligned chunk
 // holds result of comparing 16 bytes where each DWORD is either all bits on or off
 // PCMPEQD
 // MOVMSKPS
 // There is at least one difference in the 16 bytes - find the first diff. byte
 // nothing required in the loop body
 // else we have done something wrong (or PCMPEQD did not work)
 // Check up to 15 bytes past the last 16-byte aligned chunk
