Относительно написания собственной функции memcpy
для пользовательского загрузчика и ядра, я решил изучить различные аспекты написания хорошей и, возможно, быстрой реализации для копирования памяти на выровненных границах (например, прокрутка в режиме видео, где каждыйлиния на экране начинается с выровненной границы), но также для больших (> 1 МБ) и не выровненных структур.
Мой вопрос заключается в том, что компилятор, в моем случае GCC, поддерживает различные варианты оптимизации.параметры (либо путем включения отдельных параметров, либо с помощью O2
, O3
, ...), до какого уровня оптимизации мне нужно реализовать фактическую функцию memcpy для достижения наилучшего результата при копировании вместес флагами оптимизации GCC?
Моя текущая реализация выглядит следующим образом:
static void *memcpy_unaligned(void *dst, const void *src, size_t len)
{
size_t i;
unsigned char *d = (unsigned char *)dst;
unsigned char *s = (unsigned char *)src;
for (i = 0; i < len; i++)
d[i] = s[i];
return dst;
}
static void *memcpy_aligned16(void *dst, const void *src, size_t len)
{
size_t i;
uint16_t *d = (uint16_t *)dst;
uint16_t *s = (uint16_t *)src;
for (i = 0; i < ((len) & (~1)); i += 2)
d[i] = s[i];
for ( ; i < len; i++)
((unsigned char *)d)[i] = ((unsigned char *)s)[i];
return dst;
}
static void *memcpy_aligned32(void *dst, const void *src, size_t len)
{
size_t i;
uint32_t *d = (uint32_t *)dst;
uint32_t *s = (uint32_t *)src;
for (i = 0; i < ((len) & (~3)); i += 4)
d[i] = s[i];
for ( ; i < len; i++)
((unsigned char *)d)[i] = ((unsigned char *)s)[i];
return dst;
}
static void *memcpy_aligned(void *dst, const void *src, size_t len)
{
/* Are dst and src aligned on a 4-byte boundary? */
if (ALIGNED(dst, src, 4))
return memcpy_aligned32(dst, src, len);
/* Are dst and src aligned on a 2-byte boundary? */
if (ALIGNED(dst, src, 2))
return memcpy_aligned16(dst, src, len);
return memcpy_unaligned(dst, src, len);
}
void* memcpy(void *dst, const void *src, size_t len)
{
return memcpy_aligned(dst, src, len);
}
Полезно ли также проверять, совпадают ли указатели dst
и src
на нечетных границах только для первых или первых трех байтов, чтобы сначала сделать однобайтовую копию, а затем word
и dword
копирование?