- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
void * c_memmove(void *dest, void *src, size_t n)
{
void *ret = dest;
if (n)
{
*(__int8 **)&dest += n;
*(__int8 **)&src += n;
switch (int x = n % 4)
{
do
{
if (!!'true')
{
case 0:
*--*(__int32 **)&dest = *--*(__int32 **)&src;
n -= 4;
}
else
{
case 3:
*--*(__int8 **)&dest = *--*(__int8 **)&src;
case 2:
*--*(__int8 **)&dest = *--*(__int8 **)&src;
case 1:
*--*(__int8 **)&dest = *--*(__int8 **)&src;
n -= x;
}
} while (n);
}
}
return ret;
}
Lure Of Chaos 11.11.2011 21:22 # 0
это что за хэш?
Dummy00001 12.11.2011 04:46 # 0
bugmenot 11.11.2011 21:28 # +3
istem 11.11.2011 21:41 # 0
defecate-plusplus 11.11.2011 21:48 # 0
Lure Of Chaos 11.11.2011 22:08 # +1
TarasB 11.11.2011 23:34 # 0
чем отличается от
(_int8*)dest
?
Dummy00001 12.11.2011 04:47 # 0
TarasB 12.11.2011 12:30 # 0
pushkoff 12.11.2011 20:40 # +2
для некоторых это критично
defecate-plusplus 12.11.2011 01:34 # +2
код является тонкой вариацией на тему http://govnokod.ru/8397, но при этом умудряется выполнять почти ровно то, что задумано, т.е. тут по делу все эти несчастные if и while
даже 'true' ок
да, *--* это скорее ради гламура
какие проблемы я вижу в этом коде:
1) это memcpy, а не memmove
2) аргумент src должен быть void const *
3) - самое главное - похвальная попытка копировать блоками по 4 байта, которая однако не приведет к желаемому результату, если либо src, либо dest не будут на момент входа в функцию сами выровнены по границе слова
я даже подозреваю кто это запостил
Dummy00001 12.11.2011 04:50 # −1
потому что фэйк.
почти все современные компилеры способны сами съоптимизировать эти операции.
а те у кого нету человеческого или современного компилера, киздят код из BSD.
defecate-plusplus 12.11.2011 09:15 # +3
те, у кого нет человеческого компилера, пользуются старым добрым побайтным memcpy или memmove, потому что платформа может показать кукиш при невыровненном обращении руками (и потом кури логи при загрузке embedded ОС), либо соптимизировать это таким образом, что побайтно быстрее (иначе, например, берет исходное слово, заменяет в нем байт, кладет обратно)
и да, поделишься сорцами memcpy.c из бсд? а то гугл мне находит в основном только версию "This is designed to be small, not fast.", делающую по-миссионерски
gegMOPO4 12.11.2011 15:28 # 0
63F45EF45RB65R6VR 12.11.2011 16:30 # +2
если компилить как .c код то кастинг дает lvalue
а если как .cpp то rvalue и вываливается с такой ошибкой
error C2105: '--' needs l-value
поэтому
*(__int8 **)&dest
чем отличается от
(_int8*)dest
?
второй вариант просто не скомпилируется в .cpp режиме
а когда мы берем адрес указателя и разыменовываем то получаем
lvalue и в .c и в .cpp режиме потом делаем декремент и еще одно
разыменование для записи копируемых данных так что нет не для гламура
TarasB 12.11.2011 20:52 # 0
63F45EF45RB65R6VR 12.11.2011 16:43 # 0
блоки перекрывающиеся можно было копировать а memcpy
копирует сначала так что по поведению это чистый memmove
defecate-plusplus 12.11.2011 19:43 # 0
defecate-plusplus 12.11.2011 19:55 # 0
если dest < src, то копировать с головы, иначе - с хвоста
pushkoff 12.11.2011 20:45 # 0
memcpy нет, и линус от этого получает неимоверный батхерт, он даже предлагал сделать memcpy синонимом memmove
defecate-plusplus 12.11.2011 21:26 # 0
That said - why the heck would you ever do memcpy() backwards? Things like automatic prefetchers usually work better for the "natural" patterns, so a backwards memcpy is generally a bad thing to do unless you have some active reason for it, like doing a memmove()
JavaGovno 18.05.2012 16:21 # 0
но на интелах это решается установкой/сбросом флага
что в ЧПУ, что в ДМА
SadKo 19.05.2012 00:40 # +1
А вот разработчики Intel и AMD пошли дальше и написали код, делающий memcpy/memmove сначала через mmx, потом через xmm-регистры. И судя по тестам он намного быстрее на больших объёмах памяти. Вот так вот.