Самый быстрый метод на x86-64, чтобы проверить, не перекрывает ли диапазон указателя адрес, выровненный по N байтам?

Учитывая указатель на T, я хотел бы определить, не перекрывает ли T адрес, выровненный по N байтам. На практике меня волнует только то, имеют ли объекты размером 0-5 байт границы 8 или 16 байтов, но я написал эту общую версию:

template<class T, unsigned long N>
bool straddlesBoundary(T* obj)
{
unsigned long before = (unsigned long)obj & ~(N-1);
unsigned long after  = ((unsigned long)obj + sizeof(T) - 1) & ~(N-1);
return before != after;
}

По сути, округляем адрес до ближайшего N-байтового выровненного адреса, затем возьмем приращение указателя на величину T минус один (потому что T, заканчивающийся прямо на следующей границе, не считается стреловым) и округлим его до ближайшего Выровненный по байту адрес, и если они совпадают, вы знаете, что это не колеблется.

Есть ли более быстрый способ сделать это? Я только что сделал это, я не знаю, есть ли стандартная проверка.

Изменить: Обратите внимание, я предполагаю, что T меньше, чем N.

0

Решение

Вы могли бы сделать:

unsigned long offset = (unsigned long)obj & (N-1);
return offset > N - sizeof(T);

(этот код, как и ваш, работает, только если N является степенью 2.)

5

Другие решения

Других решений пока нет …