Здравствуйте, CrystaX, Вы писали:
CX>memcpy может копировать не только побайтово. Смотри здесь.
Я бы сказал "в некоторых случаях некоторые версии" memcpy могут копировать оптимальнее.
Думаю заказчика неудовлетворит программа которая ИНОГДА работает так как надо.
CX>Насчет этой книги уже все сказали здесь
Здравствуйте, arcman, Вы писали:
A>Здравствуйте, CrystaX, Вы писали:
CX>>memcpy может копировать не только побайтово. Смотри здесь. A>Я бы сказал "в некоторых случаях некоторые версии" memcpy могут копировать оптимальнее. A>Думаю заказчика неудовлетворит программа которая ИНОГДА работает так как надо.
Перед тем, как отдавать программу заказчику, ее нужно тестировать и замерять профайлером. Тогда никаких проблем с производительностью не будет. И даже если в данном случае memcpy не будет заоптимизирована, это важно только в случае очень частого ее использования в программе. Заказчику вообще будет наплевать с помощью чего копирование реализовано — лишь бы работало и не тормозило.
CX>>Насчет этой книги уже все сказали здесь
.
A>Лично у меня абсолютно другое мнение о книге и об авторе в общем.
это действительно книжка, которую действительно абсолютно не жалко выкинуть. Полезной информации там — ровно ноль. Этакая беллетристика. От нечего делать почитать можно, но и только.
Здравствуйте, CrystaX, Вы писали:
CX>Перед тем, как отдавать программу заказчику, ее нужно тестировать и замерять профайлером. Тогда никаких проблем с производительностью не будет. И даже если в данном случае memcpy не будет заоптимизирована, это важно только в случае очень частого ее использования в программе. Заказчику вообще будет наплевать с помощью чего копирование реализовано — лишь бы работало и не тормозило.
Извиняйте — тема называется "быстрое копирование памяти". Наверное автор как раз имеет критический участок и его врядтли устроят варианты "возможной оптимальной работы".
CX> это действительно книжка, которую действительно абсолютно не жалко выкинуть. Полезной информации там — ровно ноль. Этакая беллетристика. От нечего делать почитать можно, но и только.
В книге полностью построенной на практических примерах неможет быть "ноль полезной информации".
Вы неправы. Автор подробно разобрал вопрос копирования памяти, во всех возможных вариантах.
Здравствуйте, arcman, Вы писали:
A>Извиняйте — тема называется "быстрое копирование памяти". Наверное автор как раз имеет критический участок и его врядтли устроят варианты "возможной оптимальной работы".
Именно поэтому прежде чем спорить насчет memcpy, по хорошему следовало бы посмотреть на генерируемый в конкретной ситуации код.
... << RSDN@Home 1.1.4 stable rev. 510>>
Выяснение отношений. Censored. -- ПК
Re[4]: быстрое копирование памяти через FPU ЧЕРЕВАТО!!!
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>ага, значит быстрее все-таки, А>>не знаю, что все так к выравниванию прицепились, А>>копируется в общем случае N байт, остаток отдельно, А>>главное основную часть быстро скопировать
E>1) Быстрее может быть из-за FPU и если всё в кэше, а так один хрен как через проц гнать -- гнлавное до него пошине дотащить и обратно.
Может я не в тему, но если ты будешь копировать raw memory double'ами, то получишь исключение, так как не любая последоватьльность бит есть валидное вещественное число. На clc++(m) это обсуждалось.
E>2) Чего все к выравниванию прицепились. Есть две причины. Обе архитектурного толка. E> Причина №1 состоит в том, что реально проц с памятью обменивается не байтами, а словами или даже большими пачками бит. Но это только выровнеными словами. Поэтому если вы читаете выравненное слово, то это происходит за один цикл общения с памятью, а если таки невыравнное, то за два. В результате в два раза медленне. А если байт, то всегда за один, но только байт.
Когда ты читаешь байт из памяти, по-любому загружается кэш линейка процессора. Далее чтение идет из кэша и уже выравнивание на скорость чтения влияния не оказывает.
Про mmx/sse/... я не в курсе, там, возможно, есть возможность копировать/читать минуя кэш.
E>Скажем тачка 32-битная. Тогда при побайтовой пересылке за цикл обмена с памятью прокачаете 8 бит, при невыравненной пословной, в среднем 16, а при выравненной пословной 32 -- в разы эффект-то
Опять же, цикл обмена с памятью — это цикл обмена целой кэш линейки, один байт/слово в память не пишется, только линейка целиком.
Здравствуйте, arcman, Вы писали:
A>Здравствуйте, MaximE, Вы писали:
ME>>memcpy работает независимо от выравнивания данных и обычно заоптимизирован чтобы копировать машинными словами или используя mmx/sse/sse2/.... A>Скорее memcpy иногда "заоптимизирован".
На современных процессорах rep movsd в микрокоде заоптимизирован, смысла выпендриваться большого нет. rep movsd.
A>Здравствуйте, Erop, Вы писали: E>>(если скомпилируется просто в пересылки слов, то вообще-то смысла в такой оптимизвции не много) A>Смысла почти в четыре раза — копирование двойными словами происходит гораздо быстрее нежели просто побайтно и является одним из самых оптимальных вариантов копирования памяти.
E>>И если на архитектуре словами веселее выходит, то memcpy словами копировать будет A>Мы не в сказке живём, memcpy копирует побайтово.
меня удивляет до чего программисты которые "C-программисты всегда хотят знать больше подробностей (c) RSDN" могут доходить в споре до такого бреда. неужели никто из вас ни разу не попробовал заглянуть в окно дизассемблера?
во-первых, не глядя вообще никуда в среде разработки можно сказать что ДЛЯ ПРИВЕДЁННОГО примера ВТОРОЙ вариант БЫСТРЕЕ. если же все-таки глядеть, то:
соотв. же строка "memcpy(p1, p2, 8)" только по одному вызову почти равняется приведённому коду.
во-вторых, в нормальных программах (читай "скомпилированных компилятором, настроенным нормальным программистом") выравнивание всегда кратно четырём (выравнивание QWORD хоть и предусмотрено, но реальной пользы в его использовании я не вижу). это я о фразе "выравнивание, подходящее для double" (это что за новое слово в программировании? если на то пошло, то DOUBLE'у, как и любой структуре в памяти, даже выравнивание BYTE подойдёт).
в-третьих, настолько бездарно написать код копирования памяти могли только в microsoft'e (я не имею ничего против них, но все-таки). любой студент второго/третьего курса знает об инструкции MOVSD в сочетании с REPNE/REPNZ и напишет код, который короче в несколько раз и полностью поддается оптимизации процессором, в отличие от представленного в файле 'memcpy.asm'. интересущимся советую открыть соотв. исходники модуля System.pas среды Delphi и посмотреть как НАДО писать такие процедуры (копирование памяти выполняется с 4-хбайтным выравниванием, по возможности, обращаю внимание, а не с 2-хбайтным, как у MSVC).
итог: если пользовать memcpy() то неплохо бы для начала переписать её КАК НАДО. если копировать стандартные типы WORD DWORD DOUBLE FLOAT и прочее, то не надо никакой memcpy().
Этот (правильный) код мы запомним, коментарий ниже: P>mov eax,dword ptr [p1] P>mov ecx,dword ptr [p2] P>mov edx,dword ptr [ecx] P>mov dword ptr [eax],edx P>mov ecx,dword ptr [ecx+4] P>mov dword ptr [eax+4],ecx
P>соотв. же строка "memcpy(p1, p2, 8)" только по одному вызову почти равняется приведённому коду.
P>во-вторых, в нормальных программах (читай "скомпилированных компилятором, настроенным нормальным программистом") выравнивание всегда кратно четырём (выравнивание QWORD хоть и предусмотрено, но реальной пользы в его использовании я не вижу). это я о фразе "выравнивание, подходящее для double" (это что за новое слово в программировании? если на то пошло, то DOUBLE'у, как и любой структуре в памяти, даже выравнивание BYTE подойдёт).
Весьма опрометчивое заявление. Ты хоть подозреваешь о существовании других процессорных архитектур, или для тебя свет клином сошелся на x86? Да и x86 начиная с 486 умеет прерываться по обращению к невыровненной панмяти, если установлен соответсвующий флаг. Кто гарантирует тебе, что в конкретном случае это будет не так?
P>в-третьих, настолько бездарно написать код копирования памяти могли только в microsoft'e (я не имею ничего против них, но все-таки). любой студент второго/третьего курса знает об инструкции MOVSD в сочетании с REPNE/REPNZ и напишет код, который короче в несколько раз и полностью поддается оптимизации процессором, в отличие от представленного в файле 'memcpy.asm'. интересущимся советую открыть соотв. исходники модуля System.pas среды Delphi и посмотреть как НАДО писать такие процедуры (копирование памяти выполняется с 4-хбайтным выравниванием, по возможности, обращаю внимание, а не с 2-хбайтным, как у MSVC).
Нет, ну какой-то за.....ц наехал на мою любимую компанию. Этого я так не оставлю. Да ладно бы еще по делу — это можно было бы и стерпеть, а тут — ну совершенно без повода. Короче, слушай сюда, коль сам напросился на порку: то, что ты предлагаешь — даже не вчерашний и не позавчерашний день, а просто доисторическая эра. Ты застрял на уровне Intel 8088. Для них ТАК действительно было оптимально. Короче, БЕГОМ В БИБЛИОТЕКУ. Начни со статьи "Опмизация программ на ассемблере для i486 и Pentium" (потом ты поймешь, что для последующих процессоров, начиная с пня-про, ситуация еще более актуальна).
Ладно, специально для тебя цитирую:
3.6. Какие команды использовать ?
1) Уже на i486 оптимизировались лишь так называемые часто используе-
мые команды: mov, add, sub, neg, inc, dec, xor, or, and, not, cmp,
test, команды сдвига и ветвления. Поэтому оказывается лучше использо-
вать вместо "тяжеловесных" команд последовательности простых.
Hа Р5 только простые команды являются спариваемыми (см. приложение).
Пример:
U V
rep movsd — ; 4 такта
--------------
1 байт за такт
Разворачивая цикл дальше, в пределе получаем 4 байта за такт.
Теперь ты понял, почему мелкомягкие сделали именно так? Так кто из вас двоих (ты или M$) идиот?
Далее лезешь на сайт Интел и скачиваешь доки по их процессорному ряду x86. Самый важный документ для тебя — Intel Architecture Optimization Manual. Скачиваешь его (для каждой модели процессора он свой) и читаешь медленно и вдумчиво до просветления. Особое внимание обращаешь на различные stall'ы.
P>итог: если пользовать memcpy() то неплохо бы для начала переписать её КАК НАДО. если копировать стандартные типы WORD DWORD DOUBLE FLOAT и прочее, то не надо никакой memcpy().
Да, а тебе НЕПЛОХО БЫ прежде чем высказывать суждения по какому-либо поводу, получить хотя бы поверхностное представление об обсуждаемых вещах. Короче: СУДИ, ДРУЖОК, НЕ ВЫШЕ САПОГА.
PS. А что, дельфятник действительно выдает "REPNZ MOVSD" при включенной оптимизации по быстродействию? Если ответ "ДА", выкинь его на помойку и перейди на что-нибудь более современное/эффективное.
Re[4]: быстрое копирование памяти
От:
Аноним
Дата:
22.08.05 06:33
Оценка:
Здравствуйте, MaximE, Вы писали:
ME>На современных процессорах rep movsd в микрокоде заоптимизирован, смысла выпендриваться большого нет. rep movsd.
Только на достаточно больших массивах памяти. Читаем "Intel Architecture Optimization Manual" для второго пня, раздел 3.5.2. Одно из условий эффективности этого кода таково: "The length of the data must require greater than 64 repetitions". В приведенном в мануале примере копируется полная страница (4096 байт). Мой опыт подсказывает мне, что обычно копируются меньшие объемы данных.
Самое быстрое копирование памяти — то, которого не происходит. Т.е. прежде чем искать что-то быстрее memcpy может стоит задуматься — а нужно ли это копирование вообще? Что-то я не могу вспомнить, когда мне нужно было копировать большие объемы данных из системной памяти в системную память. Бывает нужно копировать из системной в какую-то другую (например в вершинный буффер видеокарты) — но тут уже скорость определяется пропускной способностью, а не тем чем именно производится копирование (конечно если не делать каких-то жутких извращений).
В случае же копирования системная память -> системная память проще вообще исключить копирование.
Здравствуйте, <Аноним>, Вы писали:
А>аа, если машинными словами..., то это другое дело, А>я заходил тут в один memcpy, он там просто побайтно А>бежал и копировал, я вот хотел ему помочь
Случайно не реализацию от Майкрософт имеешь в виду? Там надо быть внимательным — многие увидят вот этот код в memcpy.c
void * __cdecl memcpy (
void * dst,
const void * src,
size_t count
)
{
void * ret = dst;
#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlMoveMemory( void *, const void *, size_t count );
RtlMoveMemory( dst, src, count );
}
#else/* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
/*
* copy from lower addresses to higher addresses
*/while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
#endif/* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */return(ret);
}
и бегут миру трезвонить о тупости программеров из мелкософта, тупее которых только некоторые программеры из мелкософта. Однако все не так плохо: реально используемая имплементация находится в Intel/memcpy.asm. И там все вполне нормально — добивается по выравниванию, дальше гонится двойными словами. Так что хватит ерундой заниматься — memcpy действительно работает!
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, Антипка, Вы писали:
А> Хай, Progger, Вижу, ты тут наколбасил: <...> Ты хоть подозреваешь о существовании других процессорных архитектур <...> Нет, ну какой-то за.....ц наехал на мою любимую компанию. <...> Короче, слушай сюда, коль сам напросился на порку: <...> Ладно, специально для тебя цитирую: <...> Так кто из вас двоих (ты или M$) идиот? <...> Да, а тебе НЕПЛОХО БЫ прежде чем высказывать суждения по какому-либо поводу, получить хотя бы поверхностное представление об обсуждаемых вещах. Короче: СУДИ, ДРУЖОК, НЕ ВЫШЕ САПОГА.
5. Не допускается проявление грубого или неуважительного отношения к другим участникам форума. Оскорблять и обзывать собеседника, ставить под сомнение его профессиональную квалификацию, придираться к его нику, указывать на орфографические и синтаксические ошибки и т. д. запрещается.
Бан 2 суток. Вопросы и замечания по модерированию форумов РСДН — в .
--
ПК
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Progger, Вы писали:
P>меня удивляет до чего программисты которые "C-программисты всегда хотят знать больше подробностей (c) RSDN" могут доходить в споре до такого бреда <...> в нормальных программах (читай "скомпилированных компилятором, настроенным нормальным программистом") <...>
5. Не допускается проявление грубого или неуважительного отношения к другим участникам форума. Оскорблять и обзывать собеседника, ставить под сомнение его профессиональную квалификацию, придираться к его нику, указывать на орфографические и синтаксические ошибки и т. д. запрещается.
Бан 1 сутки. Вопросы и замечания по модерированию форумов РСДН — в .
--
ПК
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен