Вопрос по поводу модифицированного алгоритма GNU - PullRequest
2 голосов
/ 30 июня 2010

Я прочитал статью Оптимизация Memcpy улучшает скорость , у меня вопрос по поводу алгоритма модифицированного GNU, я получаю сообщение об ошибке при запуске кода src & 0xFFFFFFFC, src - указатель void, может ли это бытьлевый операнд для «&»?Я что-то здесь упустил?

Спасибо

Ошибка 1 ошибка C2296: '&': недопустимо, левый операнд имеет тип 'const void *'

void * memcpy(void * dst, void const * src, size_t len)
{
    long * plDst = (long *) dst;
    long const * plSrc = (long const *) src;
    if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))
    {
        while (len >= 4)
    {
            *plDst++ = *plSrc++;
            len -= 4;
        }
    }
    char * pcDst = (char *) plDst;
    char const * pcSrc = (char const *) plSrc;
    len += 4;
    while (len--)
    {
        *pcDst++ = *pcSrc++;
    }
    return (dst);
}

Ответы [ 3 ]

1 голос
/ 20 апреля 2011

Не уверен, что это так долго оставалось без ответа.Стандарт C на самом деле не может быть более ясным по этому вопросу. C99 §6.5.10 (битовый оператор AND):

Ограничения

Каждый из операндовимеют целочисленный тип.

Таким образом, вам нужно привести указатели к целым числам, прежде чем они могут быть использованы в качестве операндов &;в частности, вы должны привести их к intptr_t (или uintptr_t), для чего стандарт гарантирует, что «любой действительный указатель на void может быть преобразован в этот тип, затем преобразован обратно в указатель на void, и результат будет сравниваться равнымк исходному указателю "

#include <stdint.h>
...
if ((intptr_t)src & 3) {
   // src does not have 4 byte alignment
}

Есть и другие проблемы с вашим кодом, но добавление приведений позволит вам перейти к их поиску.

1 голос
/ 30 июня 2010

Вы можете указывать битовые маски - это законная операция, если вы знаете, что делаете.

Прежде всего, убедитесь, что ваш компилятор не в режиме C ++ (поскольку онMSVC ++) - это должно быть предупреждением в C, а не ошибкой.

Во-вторых, 0xFFFFFFFC - это целое число - вы должны выполнить соответствующее приведение для рассматриваемой операции (сделайте ее типом указателя).

В-третьих, я ожидаю, что ваш компилятор / libc уже имеет фантастическую реализацию memcpy - используйте встроенную, а не вашу собственную версию.Компиляторы выполняют некоторые хитрости с функциями C и стандартной библиотеки, и могут даже встроить и развернуть циклы memcpy.Когда вы делаете свой собственный memcpy, этот трюк обычно не выполняется.

0 голосов
/ 20 апреля 2011

Я прочитал похожую статью на http://www.eetimes.com/design/embedded/4024961/Optimizing-Memcpy-improves-speed/, и мне кажется, что

if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))

не проверяет выравнивание указателей.

, например,если src равно 0x13 (нечетно), то src & 0xFFFFFFFC равно 0x10.! (0x10) равно 0, так что if терпит неудачу.отлично.

если src выровнен, скажем, 0x14, то src & 0xFFFFFFFC равен 0x14.! (0x14) равно 0, так что if терпит неудачу.упс.

Я думаю, что это подходящая проверка:

if (!(src & 0x3) && !(dst & 0x3)) {
   // pointers are aligned, copy in 32 bit chunks
   ....
}

и я также не вижу цели в len + = 4;но я предполагаю, что оригинальный вопрос был просто об ошибке компиляции, так что весь этот ответ несколько отступает, и, возможно, я неправильно понял, как это должно работать.(и я согласен с оригинальным ответом, просто используйте то, что есть в библиотеке).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...