![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
ForceKeeper |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
Из праздного интереса сравнил производительность на своем ПК родного memcpy и такого цикла
Дефолтная функция оказалась в 10-11 раз быстрее. Может кто знает, что за сильное колдунство в ней применено? P.S. mas - интовский массив, так что, если я ничего не путаю, проблем с выравниванием по вордам не должно быть |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
копирование двойными словами или четвертными словами.
|
|||
|
||||
newbee |
|
|||
![]() Бревно ![]() ![]() Профиль Группа: Участник Сообщений: 703 Регистрация: 24.8.2011 Репутация: 3 Всего: 19 |
AFAIK в memcpy используются какие-то специальные ассемблерные функции. Как msvc не знаю, а GCC при -03 выравнивает производительность memcpy и наколеночной реализации.
Добавлено через 1 минуту и 9 секунд Утром исходник посмотрю. -------------------- You're face to face With man who sold the world |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Посмотрите исходники. все ран-таймовские сорцы должны быть. Вот исходник от 2008 студии (2010 под рукой нет, но думаю там ничего кардинального с memcpy не произошло)
Такая разница из-за того что вы скорей всего в дебаге собрали. Нужно собирать в релизе, с ключами оптимизации на скорость. к тому-же шорты немного медленней чем инты, или чары. Но главное оптимизация! Это сообщение отредактировал(а) volatile - 6.9.2011, 03:00 |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
пример: http://notes.sochi.org.ru/1322/
в CRT GCC что-то вроде этой. но посложнее. еще помню, однажды для копирования массивов, нужна была ооочень быстрая memcpy(). я в инетах нашел кучу. но тесты показали, что дефолтная нисколько не медленнее. Добавлено через 1 минуту и 3 секунды
позор! ![]() |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
побайтное копирование!
![]() Добавлено через 6 минут и 56 секунд volatile, посмотри на это? http://lxr.linux.no/linux+v3.0.4/arch/x86/...tring_32.h#L168 выше реализованы использованные в ней функции. Добавлено через 8 минут и 31 секунду одна из них в другом файле: http://lxr.linux.no/linux+v3.0.4/arch/x86/lib/mmx_32.c#L28 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Где-то в старом борланде я видел асмовую memcpy, с копированиями 32-разрядными словами. Внешне очень красивая. с трюками и развернутыми циклами. щас не могу найти. может завтра.. Но в реале она боюсь окажется не на много быстрее... Это связано с современными процессорами. Там основное время тратится на не попадание в внутренний кеш процессора. (страница памяти). И это невелирует различия побайтного и пословного копирования. Вообще может сравню раельную производительность, если будет время. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
кеш может на что-то повлиять, если происходит копирование массивов размером меньше линии кеша. это первое. второе - т.к. массивов два(источник-приемник), то тогда оба массива должны попасть каждый в свою линию(иначе толку от одного кеша не будет). а это маловероятно. третье - копирование словами/двойными_словами - всегда быстрее. сравни. Это сообщение отредактировал(а) boostcoder - 6.9.2011, 03:35 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Пример: 1. Побайтое копирование читаем первый байт, который не находится в кеше. тратим на это 1000 тактов. (грубо) читаем второй байт (а он уже в кеше) тратим на это 2 такта читаем 3 -ий байт тратим 2 такта читаем 4 -ый байт тратим 2 такта итого 1006 тактов. 2. Теперь читаем словами. читаем слово, не попадаем в кеш, тратим 1000 тактов. итого разница между побайтным и пословным копированием 1000 против 1006. Цифры взял с потолка, просто чтоб объяснить свою мысль. не спорю. просто возможно что не на много. Реально может сравню. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
размер линии кеша - 64 байта. а теперь посчитай сколько тактов потребуется для копирования массива объемом 128 байт, к примеру ;) |
|||
|
||||
Silent |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 252 Регистрация: 3.10.2006 Репутация: 1 Всего: 9 |
Решил проверить, делая ставку на стандартную memcpy:
Результат неожиданный:
Конфигурация - VS2010, WinXP SP3, i3, 2Gb. Проверил на VS2008 - результат аналогичный. Посмотрел в ассемблерный листинг - самописанные процедуры в обоих студиях записались так:
(копирование строки с адреса ds:esi в адрес es:edi) А вот memcpy - вызов внешней функции:
Эм... дефолтная функция не умеет использовать процессор на всю катушку? |
||||||||
|
|||||||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
volatile же показал код memcpy() используемой в VC2008. чего он нее ожидать-то?
![]() |
|||
|
||||
Silent |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 252 Регистрация: 3.10.2006 Репутация: 1 Всего: 9 |
ну я не знаю... надеялся на оптимизационные способности компилятора )))
|
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Ребята, современные процессоры, довольно сложные штуковины. там 3 уровня кеша. К тому-же GetTickCount(); слишком груба чтобы сравнивать промежутки времени меньше минуты у нее слишком большая дискретность. Но дело здесь не в этом. Здесь дело в страничном выделении памяти. Первая процедцра копирования работает с не выделенной памятью и тратит кучу времени на выделение этой памяти. Вторая уже работает с выделенной памятью. Просто поменяйте функции местами, и скорость получится не в вашу пользу с точность до наоборот
Просто меняю очередность вызовов местами:
Функции брал ваши без переделки. ![]() |
||||
|
|||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Реализация в VS 2010 на ASM. Влезьте внутрь, все увидите.
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Estranged, куда влезать то? В бинарник? Дык там конечно асмовые инструкции. Просто приведите исходник, все исходники CRT идут со студией. 2010 студии под рукой нет, просто интуитивно, не думаю что в 2010 стали переписывать стандартные библиотеки на асме, времена не те... |
|||
|
||||
voral |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Вон, что гугл наше на микрософтовом сайте http://research.microsoft.com/en-us/um/red...rt/memcpy.c.htm
Правда есть и такое C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\intel\memcpy.asm Это сообщение отредактировал(а) voral - 6.9.2011, 16:22 |
|||
|
||||
Silent |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 252 Регистрация: 3.10.2006 Репутация: 1 Всего: 9 |
А ведь есть еще великий и могучий SSE - никто не пользовался MOVDQA (sse2) или MOVNTDQA (sse4)?
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Да действительно, асмовая версия тоже есть. Видимо подставляются разные в зависимости от способа вызова (intrinsic/ not intrinsic), и от ключей оптимизации. Добавлено через 5 минут и 48 секунд Один мой знакомый программер как-то добивался максимальной скорости копирования. (игрушку делал) И он уверял, что именно с SSE ему удалось добиться самой максимальной скорости копирования памяти. (чуть ли не в разы) Но в подробности я не вникал, так как для моих задач и системной вполне хватает. |
|||
|
||||
ForceKeeper |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
Насчет ассемблера, открыл в Олли откомпиленый под релизом экзеншник, зашел в memcpy и вот, какой цикл там нашел
P.S.
Та же история) Это сообщение отредактировал(а) ForceKeeper - 6.9.2011, 23:48 |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
значит с этим все в порядке. ForceKeeper, покажи этот же асм-код но только с адресами. повторюсь. я тоже копал в этом направлении. но оказалось, что стандартная функция работает быстрее всех реализаций использующих MMX/3DNow которые я нашел. я показал почему ;) Добавлено через 5 минут и 21 секунду только что обратил внимание на такой момент. MMX регистров восемь. но оба кода(последний и тот что я приводил из исходников linux-kernel) работают следующим образом: 1. из источника копируется в 4 регистра. 2. из этих регистров в приемник. 3. из источника копируется в остальные 4 регистра. 4. из них в приемник. а почему не сразу из источника в 8 регистров? |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
ForceKeeper, ну раз так, то это в очередной раз показывает, что погоду в скорости копирования вносит не столько сам код, сколько попадания/промахи кеша. (верней разных кешей). У вас ведь этот код работал медленней вашей самодельной, насколько я понял? |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
voral |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Кстати у Страуструпа есть примерно следующая реализация копирования массива. Реально дает прирост по отношению к простому поэлементному копированию. (обсуждали както на киберфоруме)
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
ForceKeeper |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
Адреса команд этого кода в памяти?
Код в моих последних двух постах из родного memcpy и он работал многократно быстрее, чем мой примитивный тапок, копирующий по словам. |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
volatile |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
А это кто писал, или это было не из родного memcpy ?
|
||||||
|
|||||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Почитайте последний пост на первой странице. От простой перестановки вызовов функций, скорость меняется в 3 раза. Впрочем, возможно скоро займусь этим вопросом поближе, и сам все тщательно проверю. О результатах сообщу, если будет интересно. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
тот пост подтверждает пользу привносимую кешированием самой ОС. но никак не кешем проца. ибо я понял что ты говоришь про именно про него. |
|||
|
||||
ForceKeeper |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
Это был не я. Кстате, вот касательно выделения памяти. Когда ковырял свой тестирующий код и поменял местами выполнение своего цикла и родного memcpy так, чтобы дефолтная функция шла первой, так ее отработка стала медленнее (но все равно быстрее моего цикла). После этого я прямо перед ней кинул цикл, в котором пробегал весь массив и кидал туда числа - скорость отработки memcpy стала преждней (т.е. быстрой)
Почему неинициализированный мусор медленнее копируется? P.S. Пока писал пост, тут уже успели упомянуть кэш операционки... Это сообщение отредактировал(а) ForceKeeper - 7.9.2011, 01:01 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
ForceKeeper, упс, сорри. спутал вас. действительно сорри!!
Я вообще говорю о разных кешах. И о том что правильно измерить скорость очень трудно. Сам не раз убеждался что от простой перестановки функций, скорость может меняться в 3-4 раза. Поэтому судить о скорости по единичному измерениию не стоит. ForceKeeper, еще раз сорри! |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
уже ответил. ты знаешь...из последних нескольких постов, сложно понять о каком кеше ты говоришь ![]() |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
ForceKeeper |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
В итоге я наковырял такую функцию, она хоть и значительно быстрее простого цикла, но все равно на ПК медленнее где-то на 30-40%, а на нетбуке на 50-70% чем memcpy из VS2010
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
фигасе функция
![]() |
|||
|
||||
ForceKeeper |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 17.3.2010 Где: Минск Репутация: нет Всего: нет |
Основной цикл копирования моей функции в результирующем бинарнике идентичен тому, что в мемцпу (равзе что у меня счетчик в ecx, а в родной функции в edx) Но ощутимое отстование в скорости все равно есть, хотя во всем остальном коде есть еще только 3 цикла и то, они каждый на 64, 16 и 16 соотвественно итераций макисмум.
P.S. наверно родная функция еще что-то делает с данными, т.к. при увеличение объема копируемой информации разрыв в скорости растет, а основной цикл копирования идентичен, в то время как весь окруающий его код в моей функции можно принять сложность за константу Это сообщение отредактировал(а) ForceKeeper - 8.9.2011, 22:45 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |