Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование WRITE_REGISTER_BUFFER_ULONG  (Прочитано 23114 раз)
0 Пользователей и 1 Гость смотрят эту тему.
urock
Участник

ru
Offline Offline

« : 26-11-2008 15:21 » 

Возвращаясь к пакетной передачи данных по PCI шине... Будет ли организована пакетная передача данных от PC к устройству, если драйвер устройства вызовет команду WRITE_REGISTER_BUFFER_ULONG? Или будут идти одиночные транзакции с передачей адреса в каждой транзакции? Почему?
Записан
urock
Участник

ru
Offline Offline

« Ответ #1 : 26-11-2008 17:02 » 

Тут http://www.windowssupportforum.com/6522-burst-transaction-pci-card.html сказано, что если вызвать команду MmMapIoSpace с параметром CacheEnable = MmWriteCombined, то, используя WRITE_REGISTER_BUFFER_ULONG, burst передача может произойти, а может и нет.. Что за неопределенность?!
Записан
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #2 : 26-11-2008 17:49 » 

Откуда люди знают, склеит ли чипсет последовательно передающиеся данные, или нет? Зависит от реализации. Впринципе должен, т.к. проц сбрасывает в политике WriteCombined кеш потоком, как и всегда, когда кеширование для записи разрешено. Если северный мост реализован качественно, то он так барстом и сбросит в  PCI. Если нет - то нет, хотя не думаю, что сейчас можно встретить чипсет, на котором записи раскомбинируются..
Но это только на запись в PCI. Чтение не комбинируется в WriteCombined.
Можно выбрать другую политику кеширования, например WriteThrough или WriteBack, при которой доступен кеш для и чтения. Но при этом надо вручную сбрасывать строки кеша сразу после чтения, т.к. проц не может контролировать изменения в памяти на PCI устройстве.
« Последнее редактирование: 26-11-2008 20:42 от PredatorAlpha » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-11-2008 17:56 » 

WRITE_REGISTER_BUFFER_ULONG - одна команда "rep movsd" так что проц старается как может избавится от лишней работы...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #4 : 26-11-2008 21:16 » 

WRITE_REGISTER_BUFFER_ULONG - одна команда "rep movsd" так что проц старается как может избавится от лишней работы...

Не хотите ли взглянуть, как рекомендует делать такую ненапряжную операцию АМД ?

* memcpy_amd.zip (7.86 Кб - загружено 1026 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 27-11-2008 10:48 » 

вот уроды.
поэтому я и не люблю AMD...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #6 : 27-11-2008 10:56 » 

вот уроды.
поэтому я и не люблю AMD...

Кстати, при перелопачивании больших массивовов этот код даёт двух-трёх кратный выигрыш, даже на процессорах интелл. И этот код позволяет дать короткий 64-битный барст для PCI (хотя толку от префетчей для некешируемой памяти нет.)
Кстати, и интелл советует делать префетч для оптимизации за 2-3 линейки команд до доступа к памяти.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 27-11-2008 11:45 » 

не знаю... тут я конечно не специалист честно говоря... но уж больно обвязка большая...
и разве rep movsd не сделает барстовую передачу? по возможности?
это раз. во вторых... а вдруг кто ммх регистры уже использует? значит надо сохранять перед вызовом, а потом восстанавливать?
далее.. до 64 байт - они сами используют rep movs.
интеловский комплиятор "unrolled loop" optimization тоже делает по желанию. и не лишним if-ом, а при компиляции..
через ммх регистры блоками по 64 байта... тут не знаю...

PS хотя я правда не специалист) мои познания в асемблере остановились где то на уровне z80 и 8086 ))))
так что... не судите строго)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #8 : 27-11-2008 12:35 » 

и разве rep movsd не сделает барстовую передачу? по возможности?
Нет, не делают. Это точно, смотрели осцилографом, правда не на проце, а на PCI, но для ММХ команды movq шёл чёткий барст.
это раз. во вторых... а вдруг кто ммх регистры уже использует? значит надо сохранять перед вызовом, а потом восстанавливать?
В ядре - да. Кстати, для PCI уже для 256 байт сохранение/восстановление окупается по скорости (если поток, а не выборочно доступ к отдельным регистрам). А если учесть, что это две команды всего.....
через ммх регистры блоками по 64 байта... тут не знаю...
Увы всего лишь по 64 БИТА для movq. Но для PCI это даёт эффект. Проверено.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 27-11-2008 16:48 » 

проверю)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #10 : 19-12-2008 08:35 » 

////Увы всего лишь по 64 БИТА для movq. Но для PCI это даёт эффект. Проверено.

проверю)

Ну как проверка?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 19-12-2008 10:58 » 

увы, не до этого было... но я не забыл)
и на PCI проверить не смогу. у нас нет отображаемой памяти.
« Последнее редактирование: 19-12-2008 11:04 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #12 : 19-12-2008 14:04 » 

А на чём? На обычной памяти эффект буде минимальным.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 19-12-2008 14:29 » 

ну вот( что значит минимальным? меня именно он и интересовал...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #14 : 19-12-2008 15:28 » 

Cам не проверял, но на
http://www.rsdn.ru/Forum/message/18426.flat.aspx
есть такие цифры:

Код:
Copying 4194304 bytes for 1000 times

single movq instruction for 12769 ms
single movntq instruction for 8261 ms
qwad movntq instructions for 7752 ms
qwad movq instructions for 12317 ms
rep movsd instruction for 17555 ms

ЗЫ prefetcht0 имеет смысл использовать только тогда, когда копирутся за один проход [color=orange]32 байта[/color] — это даёт прирост порядка 10%

32 байта - это при четырёх movq/movntq (qwad в тестах)

Вообще-то сильно зависит от размера блока. Использовать movntq, если блок небольшой и данные сразу после копирования обрабатываются, смысла нет (даже вредно), т.к. потом их всё-равно проц будет вычитывать в кэш. (Хотя не знаю, ведь проц всё-равно заполняет всю линейку кеша перед обычной записью, может имеет смысл использовать movntq - ускорит копирование в прерывании, пусть потом уже в пользовательском режиме кеш заполняется).
А вот prefetcht0 не помешает, это точно (хоть и помощь на небольших блоках или наневыровненых данных помощь минимальна).

Также факторы выравнивания могут сыграть роль - для movq/movntq - это 8 байт, для prefetcht0 - 32 байта...

Это довольно старый код, возможно стоит использовать аналогичные SSE команды вместо ММХ ?
« Последнее редактирование: 19-12-2008 16:23 от PredatorAlpha » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 19-12-2008 17:54 » 

человек эти цифры опять же для AMD называл. в 2001 году... и непонятно чем и как мерил...
будет завтра время - проверю. на интеле... посмотрим)
если доберусь...(
PS опять же непонятно - выравнивание было или нет? размер блока - непонятно... короче все непонятно)
« Последнее редактирование: 19-12-2008 17:59 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #16 : 21-12-2008 10:03 » 

Я понял, что выравнивание было.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 23-12-2008 17:35 » 

хотел через rdtsc померить... но походу не получается....
придется в драйвер перенести и прерывания отключить... что ли.. но это еще больше времени надо)
и кеши все надо как-то очистить что ли. задумался над методикой тестирования)

по ходу дела львиную долю занимает перенос строки в кеш. по крайней мере даже когда memcpy(,,16) компилятором разворачивается в
Код:
	mov	ecx, DWORD PTR [ebp]
mov DWORD PTR [ebx], ecx
mov edx, DWORD PTR [ebp+4]
mov DWORD PTR [ebx+4], edx
mov eax, DWORD PTR [ebp+8]
mov DWORD PTR [ebx+8], eax
mov ecx, DWORD PTR [ebp+12]
mov DWORD PTR [ebx+12], ecx
код подправлю немного может выложу проект. я там единичную пересылку изменяю. правда rdtsc инструкция на новых процессорах почему то APIC возвращает...

а вычисленное значение тактов  аж 17000... второй повтор - 128 тактов. из них 100 на голый rdtsc уходит. еще от выравнивания кода зависит плюс минус пяток тактов.
в общем если память уже закеширована - то амд-шный варинат раза в полтора медленнее memcpy.

а если НЕ кеширована - то для этого надо статистику считать. потом прикручу если время будет.

« Последнее редактирование: 23-12-2008 19:55 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #18 : 23-12-2008 21:21 » 

Странно. Вроде ж rdtsc не защищённого режима инструкция....

Что касается АМД, то она короткие блоки (до 64 байт) тоже делает через memcpy, и тоже раскрученым циклом вместо rep movsd :

Код:
$memcpy_ic_3:
shr ecx, 2 ; dword count
and ecx, 1111b ; only look at the "remainder" bits
neg ecx ; set up to jump into the array
add ecx, offset $memcpy_last_few
jmp ecx ; jump to array of movsd's

............................................
align 4
movsd
movsd ; perform last 1-15 dword copies
movsd
movsd
movsd
movsd
movsd
movsd
movsd
movsd ; perform last 1-7 dword copies
movsd
movsd
movsd
movsd
movsd
movsd

$memcpy_last_few: ; dword aligned from before movsd's
mov ecx, ebx ; has valid low 2 bits of the byte count
and ecx, 11b ; the last few cows must come home
jz $memcpy_final ; no more, let's leave
rep movsb

А строка кеша при копировании заполняется 2 раза: первый раз при вычитке первого слова источника (для того заранее применяется prefetcht0, что бы данные хоть частично были до того в кеше), а второй раз - при записи первого слова в приёмник (тогда заносится вся линейка кеша в приёмник, потом уже там данные обновляются, для избежания этого и используется movntq). Кстати, если для приёмных данных используется выравнивание, то для записи, в т.ч. для movntq я выравнивания в коде АМД не вижу. Или источник и приёмник должны быть выравнены одинаково?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 23-12-2008 22:04 » 

да я собстно только начал... пока пытаюсь понять как вобще мерить надо) пока нет у меня понимания)
а про то что в драйвер бы тест перенести... меня смутили 17000 тактов на пересылку 16 байт. это либо память свопируемая? хотя я флаг вроде ставил...  либо я пока чего то не понял) может зря я GlobalAlloc не сделал...
вот и разбираюсь...
а может это HT у меня такой странный) кто его знает чем вторые пол-ядра занято...
PS тот код memcpy_amd() - я туда тоже вклеил...
выложу потом... если будет что выкладывать в числах)
« Последнее редактирование: 23-12-2008 22:07 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #20 : 24-12-2008 08:45 » 

HT может такое дать. Если в этот момент на "втором" ядре переключается задача, то шина памяти может затормозиться существенно.
Код memcpy_amd() некоторое время тратит на определение, каким методом пересылать, сохраняет/восстанавливает некоторые регистры процессора, потому чистому memcpy он проигрывает на коротких блоках. Тем более развёрнотому прямо в код.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 24-12-2008 13:21 » 

он не зависимо от размера проигрывал...
поскольку с кэшированием я пока не разобрался - методика такая:
выполняю первую пересылку, чтобы кэш заполнился, потом измеряю - вторую пересылку.
амдшный код проигрывает в полтора раза вплоть до блока 256 кб.
далее начиная с 512кб блока - ситуация меняется в обратную сторону. амдшный код быстрее.

теперь надо разобраться что творится без предварительного кеширования.
теперь с кешированием.
выделяю три региона. и четвертый на 16Мб.

выполняю три копирования разными методами. (repmovsd, memcpy,  memcpy_amd)
после этого выполняю копирование 16Мб при помощи rep movsd чтобы почистить кэш.

после этого измеряю все три метода. перед каждым измерением ставлю Sleep(0) чтобы обнулить текущий квант времени процесса.
амд - проигрывает от 1.5 до 2 раз memcpy.

вобще бесполезно я говорю... код немного отлажу чтоб красиво было и выложу. иначе бесполезно говорить.

PS проц P4-540 3.2GHz HT
кеш L1 16K 8-ассоциативный по 64 байта на линейку.
 L2 1Mb - аналогично
память DRAM 200МГц... время цикла 8 клоков. ну тоже много параметров. потом выложу.

PS выкладываю код код для студии 2005 той.
   ТОЛЬКО для MS-компилятора!!!! компилятор Intel код насилует... и вобще не компилит.

перед запуском проверить *.ASM файл!!!! как там что легло...

* memcpy_test.zip (6.97 Кб - загружено 1033 раз.)
« Последнее редактирование: 24-12-2008 14:26 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #22 : 24-12-2008 16:03 » 

он не зависимо от размера проигрывал...
поскольку с кэшированием я пока не разобрался - методика такая:
выполняю первую пересылку, чтобы кэш заполнился, потом измеряю - вторую пересылку.
амдшный код проигрывает в полтора раза вплоть до блока 256 кб.
далее начиная с 512кб блока - ситуация меняется в обратную сторону. амдшный код быстрее.
Последнее объяснимо - movntq не "вымывает" кеш при записи (512чтение+512запись), соответственно метровый кеш ускоряет чтение.
Проигрыш в полностью кешируемых областях тоже понятен - инструкции prefetcht здесь только лишний груз, как и вообще MMX. Всё пишется/читается в кеш, барсты ничего ускорить не могут.

выполняю три копирования разными методами. (repmovsd, memcpy,  memcpy_amd)
после этого выполняю копирование 16Мб при помощи rep movsd чтобы почистить кэш.

после этого измеряю все три метода. перед каждым измерением ставлю Sleep(0) чтобы обнулить текущий квант времени процесса.
амд - проигрывает от 1.5 до 2 раз memcpy.

Вот это странно... Даже если допустить угадывание конвеером чтений/записей, всё-равно непонятен такой разрыв...... В любом случае основное время уходит на чтение/запись памяти (строк кеша), и код тут должен быть неважен.
Код:
    if (timeOn < timeOff)
        Diff = timeOff - timeOn;
    else
        Diff = -1ULL - (timeOff - timeOn);
А это зачем? Второе выражение вообще даёт отрицательное число. Просто Diff = timeOff - timeOn; Произойдёт переполнение, но разница будет верна. 
« Последнее редактирование: 24-12-2008 16:22 от PredatorAlpha » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 24-12-2008 17:33 » 

последнее - это я перебдел конечно же)
попробуйте у себя скомпилить? если RDTSC таймер есть...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #24 : 24-12-2008 18:18 » 

Я поиграюсь на новогодних каникулах, сейчас нужно закрыть проект....
Тем более что у меня студия шестая стоит... Я больше по программированию DSP, а драйвера - поскольку-постольку...
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 24-12-2008 20:30 » 

а я наоборот) но тоже проект один - горит...  так что это я поскольку постольку... часик был поиграться.
на новогодних меня не будет, - отпуск взял до 12го.
а драйвера тут подчти не при чем - просто RDTSС абсолютное время измеряет, при копировании блоков - переключение задач может произойти. чтобы избежать - была мысль в драйверах выполнить код, с выключенными прерываниями. правда там стек сопроцессора не сохраняется.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #26 : 25-12-2008 08:19 » 

/////на новогодних меня не будет, - отпуск взял до 12го.
А меня отправили - тоже до 12-го.....
Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines