реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> memcpy - почему побайтно?
DASM
сообщение Nov 21 2013, 16:14
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



598 */
599 void *memcpy(void *dest, const void *src, size_t count)
600 {
601 char *tmp = dest;
602 const char *s = src;
603
604 while (count--)
605 *tmp++ = *s++;
606 return dest;
607 }
608 EXPORT_SYMBOL(memcpy);
Такой вот сурец из string.c ... видел более оптимизированную версию с раскруткой цикла. Что то не понимаю, это же дикие тормоза на 32 битнике. Но люди то солидные писали, в чем прикол?
Собственно это вариант общий для разных процев, обрамлен ifndef ARCH_MEMCPY, но. для Арм версия такая
for (i = __n >> 3; i > 0; i--) {
15 *d++ = *s++;
16 *d++ = *s++;
17 *d++ = *s++;
18 *d++ = *s++;
19 *d++ = *s++;
20 *d++ = *s++;
21 *d++ = *s++;
22 *d++ = *s++;
23 }
Что не шибко лучше.
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Nov 21 2013, 16:30
Сообщение #2


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(DASM @ Nov 21 2013, 20:14) *
...Что не шибко лучше.


вроде как у мелкомягких было сразу по регистру перекидовали. перед циклом - деление на размер, после - добивание побайтно.

в проекте с армами пока не дошёл, до копирования памяти (только вот начал упаковку изернет стэка). обращу внимание, спасибо!

и... глупый вопрос:
а точно оптимизация была включена при компиляции?
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 21 2013, 17:52
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Так это же исходники линуксовые, с kernel.org .Мне собственно говоря copy_to_user нужен, но он в итоге зовет этот самый memcpy. Объемы копирования большие, вот и заинтересовался скоростью.. Это же четыре обращения к памяти, в случае 32 битной и вне кеша — это даже не в четыре раза потеря, поболее может быть вроде как. char * никакой оптимизатор имхо заменять права не имеет на int*
Go to the top of the page
 
+Quote Post
mantech
сообщение Nov 21 2013, 18:13
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(DASM @ Nov 21 2013, 21:52) *
в случае 32 битной и вне кеша — это даже не в четыре раза потеря, поболее может быть вроде как. char *


Дык наверно так делают, чтобы получить любое кол-во копируемых байт, а не кратно 4м. Например, как такой операцией скопировать 5 или 6 байт? 32х бытовое копирование запросит как минимум 8, а если память выделена только под 5?
Если уж так важна скорость, и объемы копирования не 10 байт, а значительно больше - используйте DMA в 32х битном режиме...
Go to the top of the page
 
+Quote Post
winipuh
сообщение Nov 21 2013, 19:23
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 127
Регистрация: 31-10-12
Пользователь №: 74 189



Цитата(mantech @ Nov 21 2013, 22:13) *
Дык наверно так делают, чтобы получить любое кол-во копируемых байт, а не кратно 4м. Например, как такой операцией скопировать 5 или 6 байт? 32х бытовое копирование запросит как минимум 8, а если память выделена только под 5?
Если уж так важна скорость, и объемы копирования не 10 байт, а значительно больше - используйте DMA в 32х битном режиме...

Да Вы чего? wacko.gif Гляньте исходники newlib, bionic...
Оптимизированная версия memcpy проверяет выравнивание src и dst и выбирает вариант - копирование LDM/STM блоками по 4 слова, копирование в loop-е по словам, по полусловам, по байтам.
У Cortex-A помимо этого еще есть плюшки с Neon-ом...

Полагаю, что ТС прекрасно знает это и без нас.
И вопрос его, надо полагать, заключается в том, что "WTF? Зачем тупо выбирать самый пессимистичный вариант?" (с учетом того, что эта версия memcpy откуда-то там из линуксового ядра, стало быть писал ее не дурак)...


Хотя, надо отметить, что в том же newlib-е подобный вариант тоже присутствует:
Код
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
while (len0--) {
      *dst++ = *src++;
}


Сообщение отредактировал winipuh - Nov 21 2013, 19:27
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 21 2013, 19:29
Сообщение #6


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Вот, уже была тема, где memcpy'ями мерилисьsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sasamy
сообщение Nov 22 2013, 04:02
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858



Цитата(DASM @ Nov 21 2013, 21:52) *
Так это же исходники линуксовые, с kernel.org .Мне собственно говоря copy_to_user нужен, но он в итоге зовет этот самый memcpy.


Обсуждения оптимизаций для ARM были
http://comments.gmane.org/gmane.linux.port...m.kernel/251708

чем закончилось не знаю - посмотрите исходники текущего ядра с kernel.org, возможно уже все не так пессимистично как вы думаете sm.gif По крайней мере в новостях что-то припоминаю - проскакивало про использование NEON в ядре.

Сообщение отредактировал sasamy - Nov 22 2013, 04:05
Go to the top of the page
 
+Quote Post
Harbour
сообщение Nov 22 2013, 05:46
Сообщение #8


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



в Linux все просто - народ верит только бенчмаркам, тема с memcpy всплывает в рассылке по паре раз в год, но arch-маинтейнеры не лыком шиты - и тормозной код никак не пройдет. код memcpy отличается для каждой архитектуры так как особенность конвейеров, кешей, стандартных задержек между кешем и памятью, видов и исполнения инструкций (выборка/декодирование/исполнение) у каждой one разный. более того - следует учитывать ньюансы переключения задач, сбросов кешей при этом и сохранения регистров сопроцессоров - например, код memcpy, который жестоко юзает FPU/SIMD инструкции фиг пройдет, так как при переключении задач закукуаешься их всех сохранять wink.gif
В данном случае мы видим классический loop unroll сделанный вручную под конвейер ARM, без каких либо надежд на gcc wink.gif Если есть сомнения - пишем свою версию и тестим на железе - при дальнейших раскопках лагов, все станет понятно

P.S. педивикия - unroll
Go to the top of the page
 
+Quote Post
griabig
сообщение Nov 22 2013, 08:36
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 30-09-09
Пользователь №: 52 655



Цитата(DASM @ Nov 21 2013, 20:14) *
598 */
599 void *memcpy(void *dest, const void *src, size_t count)
600 {
601 char *tmp = dest;
602 const char *s = src;
603
604 while (count--)
605 *tmp++ = *s++;
606 return dest;
607 }
608 EXPORT_SYMBOL(memcpy);
Такой вот сурец из string.c ... видел более оптимизированную версию с раскруткой цикла. Что то не понимаю, это же дикие тормоза на 32 битнике. Но люди то солидные писали, в чем прикол?
Собственно это вариант общий для разных процев, обрамлен ifndef ARCH_MEMCPY, но. для Арм версия такая
for (i = __n >> 3; i > 0; i--) {
15 *d++ = *s++;
16 *d++ = *s++;
17 *d++ = *s++;
18 *d++ = *s++;
19 *d++ = *s++;
20 *d++ = *s++;
21 *d++ = *s++;
22 *d++ = *s++;
23 }
Что не шибко лучше.


Если я правильно понял, то приведенный код для ARM взят из arch/arm/boot/compressed/string.c. Если я не ошибаюсь, то данный код используется исключительно при загрузке ядра. А "боевая" версия memcpy находится уже в arch/arm/lib/memcpy.S и arch/arm/lib/template.S и реализована полностью на ассемблере.
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 22 2013, 09:10
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Да, верно, это именно и происходит в реальности, спасибо.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01436 секунд с 7
ELECTRONIX ©2004-2016