ПрограммированиеФорумГрафика

memcpy() и ее аналоги

Страницы: 1 2 3 Следующая »
#0
16:26, 7 янв 2005

Эта тема поднималась на форуме и ни раз, но до того, что я недавно придумал, дело видимо не доходило. Для того, чтобы эффективно копировать память в ЯВУ нередко используется встроеный ассемблер, но даже при этом работа с массивами порой получается значительно медленнее, чем хотелось бы.
А вот собственно вопрос: как быстро пересылать большие массивы данных??. В masm32 v8.2 я нашел только memfill() и memcopy(). Думаю, их исходники (или что-то похожее) форумчане видели не раз, а потому приводить их не имеет смысла.  В качестве оптимизации можно предложить пересылать по нескольку двойных слов за цикл или грамотное исползование второго конвеера (чтобы исполнялись одновременно две команды). Но это не панацея. Я подумал, а что если для пересылки использовать не только целочисленные комманды, но и FPU, ведь последний может обрабатывать числа длиной по 10 байт (или можно 8) за команду (а не по 4). Или можно придумать симбиоз трех конвееров, чтобы за каждый цикл пересылать одновременно еще больще данных. Остаток можно копировать обычными методами. Думаю, не смотря на то, что FPU работает медленее, при достаточно больших массивах игра стоит свеч. Пока нет времени и желания это реализовывать. Если кто-то это уже сделал, то может дадите исходнячок или напишитевариант этой функции. А вообще в ближайшие дни постораюсь этим заняться.

#1
16:31, 7 янв 2005

std::copy + IntelC 8.1 будет быстрее всякого memcpy

#2
16:36, 7 янв 2005

2 Da1t0NIC
>>грамотное исползование второго конвеера (чтобы исполнялись одновременно две команды)
на дворе 2005 год, U,V умерли со времён первых пентиумов
вообще CyberZX дал тебе самый лучший совет
лично я пользуюсь rep movsd

#3
16:40, 7 янв 2005

В Doom3 SDK есть реализация этой функции с использованием MMX, я правда не пробовал, возможно тоже довольно быстрая реализация

#4
17:37, 7 янв 2005

имхо rep movs рулит :)

#5
18:02, 7 янв 2005

CyberZX
>std::copy + IntelC 8.1 будет быстрее всякого memcpy
Я ассемблеровщик и мне доставляет удовольствие делать все ручками:).
Neill
>В Doom3 SDK есть реализация этой функции с использованием MMX, я правда не
>пробовал, возможно тоже довольно быстрая реализация
MMX это почти тот же FPU. Команды другие но работают с теми же регистрами. В любом случае ничего кроме загрузить по такому-то и выгрузить по такому-то адресу здесь не требуется. Жаль, оказывается не первый кто до этого додумался:). Вообще же, если игра достаточно требовательная и заранее известно, что в нее можно будет играть лишь на Pentium 3 или 4, то выгоднее использовать расширение SSE и писать сразу по 16 байт, а еще лучше объединить это с FPU и целочисленными вычислениями.
_UnSeen_
>имхо rep movs рулит :)
А вот этим я и предлагаю копировать остаток

#6
18:06, 7 янв 2005

2 Da1t0NIC
>>Я ассемблеровщик и мне доставляет удовольствие делать все ручками:).
тебя здесь скоро вылечат

#7
18:26, 7 янв 2005

Da1t0NIC
Перед изобретением собственных методов советую почитать:
http://redvip.homelinux.net/varios/AMD/AMD_block_prefetch_paper.pdf

#8
19:05, 7 янв 2005

Da1t0NIC
>Эта тема поднималась на форуме и ни раз, но до того, что я недавно придумал, дело >видимо не доходило.
вот и читай те темы, нам все написано, зачем создавать еще одну.

p.s. Всем:
как отключить VSync, как найти пересечение того с этим, что лучше Dx или OpenGL, как загрузить bmp файл. Знакомо? :))))))))))))

#9
19:49, 7 янв 2005

Da1t0NIC
>Я ассемблеровщик
ну значит должен понимать, что battle neck при копировании памяти это не скорость выполнения команд процессора, а сама память, которая является по сути штука весьма медленная. по-этому не стоит заниматься оптимизацией копирования памяти в общем случае, современные компиляторы очень хорошо с оптимизируют тот же std::copy.  Хотя это не значит, что нельзя ускорить процесс копирования памяти, просто нельзя оптимизировать для общего случая.

#10
21:03, 7 янв 2005

JokerR
>на дворе 2005 год, U,V умерли со времён первых пентиумов
Кто тебе такую чушь сказал?
>лично я пользуюсь rep movsd
Ну если узать асм, что бы затормозить немного игру, то да...

#11
21:13, 7 янв 2005

2 Akad
>>Кто тебе такую чушь сказал?
Агнер Фог ночью шептал, когда мне юзергуайд 4-го пня снился
>>Ну если узать асм, что бы затормозить немного игру, то да...
конечно, для чего же ещё

#12
21:16, 7 янв 2005

Akad
Всё правильно он сказал. U и V pipe были в Pentium. В Pentium-Pro/P2/P3... (P6-архитектура) используется 1 конвеер, но несколько исполняющих блоков.

JokeR
О, уже ответил ;)

#13
22:16, 7 янв 2005

кстати, забираю свои слова про memcpy назад :)
современные компиляторы воспринимают memcpy как интристик, так что это наиболее быстрая реализация копирования памяти. вот например такую конструкцую

memcpy(out_buffer.get(), in_buffer.get(), buffer_size);

vc7.1 заменил на

mov         esi,dword ptr [ebx]
mov         edi,dword ptr [ebx+4]
mov         ecx,1900000h
rep movs    dword ptr [edi],dword ptr [esi]

хотя

std::copy(in_buffer.get(), in_buffer.get() + buffer_size, out_buffer.get());

он заменил вызовом вручную оптимизированой функции __imp__memmove из memcpy.asm, которая даже при копировании блока 100 мегабайт, оказалась медленнее, чем простой rep movs.

сейчас проверю что сделает интеловский компилятор

#14
22:33, 7 янв 2005

Da1t0NIC
>Я ассемблеровщик и мне доставляет удовольствие делать все ручками:).
Respectz!

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.