Самый быстрый способ скопировать x элементов массива, начиная с указанного индекса c - PullRequest
1 голос
/ 03 марта 2020

Я новичок с C и играю с указателем и массивами.

Допустим, у меня есть следующая функция

GetArrayValues(uint8**pValues, uint32 *pNumValues);

где:

**pValues points to the first element of the array

*pNumValues points to the number of values in the array

Предположим, что массив содержит 100 элементов uint8.

Теперь каждый раз, когда я вызываю функцию GetArrayValues(), я хотел бы скопировать все 30 элементов, начиная с индекса 20, в новый массив:

uint8 myInternalArray[30]

Какой самый быстрый способ сделать это?

Ответы [ 2 ]

1 голос
/ 03 марта 2020

вы хотите что-то вроде этого

void *arrcpy(const void *src, void *dest, size_t pos, size_t len, size_t elemsize)
{
    const unsigned char *csrc = src;

    memcpy(dest, csrc + pos * elemsize, len * elemsize);
}

1 голос
/ 03 марта 2020

в общем; Самый быстрый способ сделать что-то - это найти способ избежать этого, а затем ничего не делать. Например, если массив и его копия не будут изменены, вы можете просто использовать разные указатели на одни и те же данные без копирования. Аналогичным образом, если что-то редко изменяется, вы можете сначала избежать копирования, а затем (редко) сделать копию, если что-то действительно изменилось.

Если вы не можете этого сделать; тогда второй самый быстрый способ - минимизировать объем работы, которого вы не избегаете. Например; копирование данных включает считывание исходных данных из одного места и запись их в другое место; но, возможно, вы можете создать копию при создании оригинала, чтобы потом не читать его оригинал.

Если вы не можете этого сделать; затем третий самый быстрый способ - использование встроенной сборки или встроенных функций. Например; для современного процессора 80x86 (с AVX2), если вы копируете 2 лишних «неиспользуемых» байта, вы, вероятно, можете сделать это с помощью 2 инструкций (загрузить 32 байта в регистр, а затем сохранить регистр в другом месте). В крайнем случае, возможно, вы можете сохранить копию в реестре и сделать это с одной загрузкой.

Если вы не можете этого сделать; тогда четвертый самый быстрый способ, вероятно, использует memcpy(). Обратите внимание, что компилятор может оптимизировать код так, что memcpy() становится таким же хорошим, как это могло бы быть с встроенной сборкой или встроенными функциями; однако в этом случае вы должны убедиться, что компилятор знает, что он может изменить 2 лишних «неиспользуемых» байта - в противном случае он будет использовать более медленный подход (чтобы не повредить что-то еще, что может быть после окончания 30-байтовая копия).

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