Автор
|
Тема: Копирование памяти
|
VuDZ |
опубликован 22-12-2001 11:56 MSK
Subj такой - надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный. Этот вопрос скорее по асму, но может кто ответит. Вот что есть сейчас:_asm { mov esi, p2; mov edi, p3; mov ecx, copy; shr ecx, 3; sub ecx, 1; // for first step l_p3: movq mm0, [esi + ecx*4]; movq [edi+ecx*4], mm0; dec ecx; jnz l_p3; } _asm emms; Дапоможите, хто чем может (желательно не теорией) ЗЫ prefetcht уже использовался - с ним только хуже mm0 + mm1 + mm2 + mm3 одновременно то же использовал. сейчвс этот код на 36% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить ? Спасибо
|
7in
|
опубликован 22-12-2001 22:42 MSK
Здесь нужно исходить из того, что... 1. Читать/записывать память лучше всего по адресу, кратному 8 (для 64-битовой шины). А т.к. возможны разные комбинации адресов, в т.ч. когда первый адрес (исходный) кратен 8, а второй (куда записываем) - нет, возникает больше трудностей, поэтому я предлагаю выравнивать хотябы один адрес (наверное, если медленнее чтение, то первый, если запись, то второй). Но это ИМХО бессмысленно, если копируются небольшие участки памяти (несколько байт). 2. Копировать лучше по 8 байт (а у тебя тут явная ошибка - не [...ecx*4], а [...ecx*8-8]). А 'sub ecx,1' здесь вообще не нужен. 3. Размер блока может быть не кратен 8, так что твой вариант надо доработать!Могу сам написать процедуру вместе с выравниванием, только ты мне напиши: 1. Что быстрее - чтение или запись? 2. Манипуляции с MMX действительно быстрее, чем 'rep movsd'? MMX производит впечатление, что должен работать быстрее, но из-за jnz (а на это наверняка и уходит основное время) на самом деле может оказаться медленнее. 3. Кстати, не ленись, попробуй копировать через FPU (загружать в ST(0) по 8 байт и записывать оттуда :) Только при тестировании проследи, чтобы адреса исходных блоков ВСЕГДА были кратны 8 (а лучше 16 :). И сделай второй тест, когда адреса на 1 больше кратного 8 значения. И не забудь, что при 'movq' делается 'shr ecx,3', а при 'rep movsd' - 'shr ecx,2'. |
VuDZ
|
опубликован 23-12-2001 06:45 MSK
1. Выравнивание везде 16 байт - это даёт ещё некий прирост в скорости 2. movq mm0, [esi + ecx*4]; - movq и копирут 64бита сразу, а та да, ошибся, ecx*8 - но разница минимальна - эти данные уже лежали в кэше 3. размер блока _всегда_ кратен 8, точнее 16 .... копирование 1Mb for 50 times MMX - 171-181 ms rep movsd - 260 ms memcpy() - 250 ms походу, ничего быстрее не придумать... |
7in
|
опубликован 23-12-2001 22:58 MSK
Почитай ещё доки об инструкциях MOVAPS/MOVUPS (для Pentium-III :) . Они записывают сразу 16 байт! Правда, [...ecx*16] уже не получится, но это вопрос номер 2... Только это уже не 'IA MMX', а 'IA MMX-2'На Athlon'е может не работать, но Athlon вроде тоже 128-битный (или я глючу?). Значит и для него что-то подобное есть... :) Удачи!!! --------------------------------------------- P.S. Кстати, попробовал я копирование через FPU (fild/fistp) на Pentium-II... Работает примерно так же, как и 'rep movsd'.
|
VuDZ
|
опубликован 24-12-2001 06:42 MSK
самый быстрый вариант [code] { mov esi, p6; mov edi, p1; mov ecx, copy; shr ecx, 3; // devide on 8 l_p3: movq mm0, [esi + ecx * 8-8]; // loading to cashe first32 bytes movq mm1, [esi + ecx * 8 - 16]; movq mm2, [esi + ecx * 8 - 24]; movq mm3, [esi + ecx * 8 - 32]; // prefetcht0 [esi + ecx * 8 - 33]; // preload next 32 bytes movntq [edi + ecx * 8], mm0; movntq [edi + ecx * 8 - 8], mm1; movntq [edi + ecx * 8 - 16], mm2; movntq [edi + ecx * 8 - 32], mm3; sub ecx, 4; jnz l_p3; } |
VuDZ
|
опубликован 24-12-2001 06:51 MSK
Ops.... что то меня проглючило _asm { mov esi, p6; mov ecx, copy; prefetcht0 [esi + ecx - 32]; // preload next 32 bytes mov edi, p1; shr ecx, 3; // devide on 8 l_p3: movq mm0, [esi + ecx * 8 - 8]; // loading to cashe first32 bytes movq mm1, [esi + ecx * 8 - 16]; movq mm2, [esi + ecx * 8 - 24]; movq mm3, [esi + ecx * 8 - 32]; prefetcht0 [esi + ecx * 8 - 64]; // preload next 32 bytes movntq [edi + ecx * 8 - 8], mm0; movntq [edi + ecx * 8 - 16], mm1; movntq [edi + ecx * 8 - 24], mm2; movntq [edi + ecx * 8 - 32], mm3; sub ecx, 4; jnz l_p3; } _asm emms;http://vudz.by.ru/misc/asm_copy.htm |
7in
|
опубликован 24-12-2001 23:51 MSK
Оригинально... Мог бы тогда уж все 8 регистров задействовать :) Раз уж всё-таки используешь prefetch0 (может, это глюк, но в моих доках без буквы 't', но это не важно), который для P-III и Athlon'ов, почитай всё-таки MOVAPS и MOVUPS и поищи аналоги для Athlon ;) |
VuDZ
|
опубликован 25-12-2001 00:16 MSK
не надо сарказма 4 регистра используются по той простой причине, что только так происходит прирост в скорости, не большо (10-15%) но есть... А это всё, что можно сделать для атлона, не ХР - SSE MMX и всё... скомпили тот файлик, на который я положил ссылку и посмотри сам на результаты - яот туды уже выкинул memcpy() и прочую фигню, но поймёшь в чём дело |
VuDZ
|
опубликован 25-12-2001 00:16 MSK
в твоих доках глюки - prefetchtx, x=0,1,2,nt |
VuDZ
|
опубликован 25-12-2001 09:11 MSK
Да. и ещё одно если цикл короткий. типа 3-4 итерации. то лучше это дело записать сплошняком - работает быстрее, учитывая архитектуру процов... по этому у меня 4 movq а посредине prefetcht0 - чтение 32 байт, прекэширование слудующих, запись... когда запись заканчивается, данные уже в кеше. а если сделать movq mm0, [] prefetcht0 [esi] movntq [edi], mm0то так только хуже будет, с всязи с тем, что данные будут прекешировать без надобности по 3 раза Всего хорошего VuDZ |
7in
|
опубликован 25-12-2001 21:09 MSK
Я б с удовольствием (скомпилировал), но у меня VC нету как такового и комп у меня P-II :(Кстати, я посмотрел - есть и prefetch, и prefetchT, и даже prefetchW оказывается :) Слушай, может, ты знаешь, где можно достать доки по всем инструкциям (желательно до P-4 и с описанием :) ??? И доки типа TechHelp и Ralf Brown's..., но поновее и покруче, а то TechHelp'а новее шестого я что-то никак не найду :) Короче, всё в этом духе... да (как в анекдоте) побольше-побольше... :))) |
VuDZ
|
опубликован 26-12-2001 06:16 MSK
1. Процессоры PentiumIII, Athlon и другие... 2. Я заказывал в саппорте AMD и техническую документацию на СД. Скоро должна прийти А так - берёш яндекс или что-то в этом роде, и начинаешь искать |