The following function compare two arrays, and returns true if all elements are equal taking in account a tolerance.
// Equal
template<typename Type>
bool eq(const unsigned int n, const Type* x, const Type* y, const Type tolerance)
{
bool ok = true;
for(unsigned int i = 0; i < n; ++i) {
if (std::abs(x[i]-y[i]) > std::abs(tolerance)) {
ok = false;
break;
}
}
return ok;
}
Is there a way to beat the performances of this function ?
Compute abs(tolerance) outside the loop.
You might try unrolling the loop into a ‘major’ loop and a ‘minor’ loop where the ‘minor’ loop’s only jump is to its beginning and the ‘major’ loop has the ‘if’ and ‘break’ stuff. Do something like
ok &= (x[i]-y[i] < abstol) & (y[i]-x[i] < abstol);in the minor loop to avoid branching — note&instead of&&.Then partially unroll and vectorise the minor loop. Then specialise for whatever floating-point types you’re actually using and use your platform’s SIMD instructions to do the minor loop.
Think before doing this, of course, since it can increase code size and thereby have ill effects on maintainability and sometimes the performance of other parts of your system.