Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный. Этот вопрос скорее по асму, но может кто ответит. Вот что есть сейчас:
_asm
{
mov esi, p2;
mov edi, p3;
mov ecx, copy;
shr ecx, 3; // devide on 4
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; // вот без этой строки iC++ Compiler ругается сильно :(
Дапоможите, хто чем может (желательно не теорией)
ЗЫ prefetcht уже использовался — с ним только хуже
mm0 + mm1 + mm2 + mm3 одновременно то же использовал.
сейчвс этот код на 36% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить :shuffle: ? А то :crash:, только мне по голове
Thanx for your attantion ;)
11.02.03 20:55: Перенесено модератором из 'C/C++' — ПК
Здравствуйте VuDZ, Вы писали:
VDZ>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный. Этот вопрос скорее по асму, но может кто ответит. Вот что есть сейчас: VDZ>
VDZ>_asm
VDZ>{
VDZ> mov esi, p2;
VDZ> mov edi, p3;
VDZ> mov ecx, copy;
VDZ> shr ecx, 3; // devide on 4
VDZ> sub ecx, 1; // for first step
VDZ>l_p3: movq mm0, [esi + ecx*4];
VDZ> movq [edi+ecx*4], mm0;
VDZ> dec ecx;
VDZ> jnz l_p3;
VDZ>}
VDZ>_asm emms; // вот без этой строки iC++ Compiler ругается сильно :(
VDZ>
VDZ>Дапоможите, хто чем может (желательно не теорией) VDZ>ЗЫ prefetcht уже использовался — с ним только хуже VDZ>mm0 + mm1 + mm2 + mm3 одновременно то же использовал. VDZ>сейчвс этот код на 36% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить ? А то , только мне по голове
Аргументы выравнены на 8 байт?
Какой типичный размер копируемых данных?
Здравствуйте VuDZ, Вы писали:
VDZ>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный.
А ты не пробовал #pragma intrinsic(memcpy)? Может не придётся и с асмом заморачиваться.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте IT, Вы писали:
IT>Здравствуйте VuDZ, Вы писали:
VDZ>>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный.
IT>А ты не пробовал #pragma intrinsic(memcpy)? Может не придётся и с асмом заморачиваться.
Это увеличивает необходимое время, незначительно, но всё таки (781 vs 761 == 2.5%)... Видимо, ММХ единственный вариант ускорить копирование...
Здравствуйте VuDZ, Вы писали:
AF>>Аргументы выравнены на 8 байт? AF>>Какой типичный размер копируемых данных?
VDZ>выравнивание 16ти байтовое VDZ>размер — от 64Kb до 16Mb, все размеры кратны 16. VDZ>Я думаю, что вообще-то это максимум, но может будут какие идеи?
В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.
Здравствуйте IT, Вы писали:
VDZ>>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный.
IT>А ты не пробовал #pragma intrinsic(memcpy)? Может не придётся и с асмом заморачиваться.
С этой прагмой memcpy разворачивается в тупой rep movsd, что совершенно неприемлемо, если данные невыравнены. Библиотечная версия пытается делать выравненную запись, в то время как на PII и PIII гораздо важнее иметь выравненное чтение (за AMD не скажу — точно не знаю, но думаю, что write combining и у них есть).
В свое время я столкнулся с ситуацией, когда нужно было делать примерно следующее.
WORD buffer1[N]; // DWORD-aligned
WORD buffer2[N]; // DWORD-aligned as well
Короче, you got the idea. Здесь получалось, что либо чтение будет DWORD-aligned, либо запись — данные так устроены. memcpy выбирала запись и проигрывала — когда я сделал свою версию, которая делала DWORD-aligned чтение, а писала как получится, она оказалась в среднем на 30% быстрее (PIII).
Но к проблеме VuDZ это отношения не имеет — он говорит, у него данные выравнены.
Здравствуйте Alex Fedotov
AF>В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.
почти в два раза быстрее, чем было :)
memcpy() отдыхает:
Copying 4194304 bytes for 1000 times
press any key to begin
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 имеет смысл использовать только тогда, когда копирутся за один проход 32 байта — это даёт прирост порядка 10%
Copying 16777216 bytes for 100 times
press any key to begin
========= test ======== read-write read write
single movq instruction 6139 ms 2664 ms 3975 ms
261Mb/s 601Mb/s 403Mb/s
single movntq instruction 3986 ms 972 ms
401Mb/s 1646Mb/s
qwad movq instructions 5658 ms 1812 ms 4006 ms
283Mb/s 883Mb/s 399Mb/s
qwad movntq instructions 3715 ms 982 ms
431Mb/s 1629Mb/s
Здравствуйте Eugene_White, Вы писали:
EW>Здравствуйте VuDZ.
EW> Есть более рациональный способ. Через "rep movs(b,w,d)" — в зависимости от требуемого. EW>Пример. EW> EW> mov ds:esi, p2 // откуда EW> mov es:edi, p3 // куда EW> mov ecx, size // сколько байт EW> rep movsb
EW>если movsw, то size/2 EW>если movsd — size/4 EW>etc...
EW>и больше ничего — скорость максимальная.
К сожалению, вы не правы — этот вариант в полтора раза медленне самого медленного MMX варианта... а до лидера (4 x movntq) надо быть более чем в три раза быстрее...
этот вариант я отбросил сразу же, после анализа — чем больше копируется в регистры за один раз, тем больше производительность...
Здравствуйте VuDZ, Вы писали:
VDZ>Здравствуйте Alex Fedotov
AF>>В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.
VDZ>1. movntq — MMX команда
За ссылку спасибо.
Ьжет вы перепутали movntq с movntps — это SSЕ команда и котрая делает почти то же самое: запись 128 битного регистра минуя кеш.
А то у меня на атлоне нет поддерки SSE
Здравствуйте VuDZ, Вы писали:
VDZ>Здравствуйте Alex Fedotov, Вы писали:
VDZ>>>1. movntq — MMX команда
AF>>Она оперирует с операндом в MMX-регистре, но появилась-то она как часть SSE. Вот, кстати, и ссылочка на эту тему нашлась: AF>>http://developer.intel.com/software/idap/media/pdf/copy.pdf
VDZ>За ссылку спасибо. VDZ>Ьжет вы перепутали movntq с movntps — это SSЕ команда и котрая делает почти то же самое: запись 128 битного регистра минуя кеш.
Чтобы завершить этот (бесполезный) спор надо попробовать выполнить movntq на PII — ставлю на STATUS_ILLEGAL_INSTRUCTION. Я смогу это сделать завтра утром (т.е. сегодня вечером по Московскому времени), если кому-то не влом сделать это раньше, буду ему премного благодарен.
VDZ>А то у меня на атлоне нет поддерки SSE
Набор команд процессоров от AMD порой пересекается с интеловскими весьма причудливым образом.
AF>Чтобы завершить этот (бесполезный) спор надо попробовать выполнить movntq на PII — ставлю на STATUS_ILLEGAL_INSTRUCTION. Я смогу это сделать завтра утром (т.е. сегодня вечером по Московскому времени), если кому-то не влом сделать это раньше, буду ему премного благодарен.
Да вроде спора и не было...
VDZ>>А то у меня на атлоне нет поддерки SSE :))
AF>Набор команд процессоров от AMD порой пересекается с интеловскими весьма причудливым образом.
Я тут закачал одну утилитку от AMD, вот результаты
features = 000013f7
CPU supports CPUID: y
CPU supports CPUID STD: y
CPU supports CPUID EXT: y
CPU supports TSC: y
CPU supports CMOV: y
CPU supports MMX: y
CPU supports 3DNOW: y
CPU supports 3DNOW_EXT: y
CPU supports AMD-K6-MTRR: n
CPU supports P6-MTRR: y CPU supports SSE MMX: y
CPU supports SSE FPU: n
и как бы это объяснить?..
странно это...
а на втором пне или целероне не пошло, недопустимая операция однако...
следовательно, k7 поддерживают SSE MMX команды, но в них нет SSE FPU, который появился в palamino...
Здравствуйте VuDZ, Вы писали:
VDZ>К сожалению, вы не правы — этот вариант в полтора раза медленне самого медленного MMX варианта... а до лидера (4 x movntq) надо быть более чем в три раза быстрее... VDZ>этот вариант я отбросил сразу же, после анализа — чем больше копируется в регистры за один раз, тем больше производительность...
Может я и погорячился насчет максимальной скорости (извините :), но давайте рассмотрим Ваш первоначальный вариант. Насколько видно, очень много тратится впустую тактов выражениями
т.е. перенос через переменные. Это замедляет работу. Неужели не лучше будет доверить это процессору командой "rep" (почему ее Алекс Федотов "давит")? Она сама уменьшает есх и "лупит" — отсюда быстродействие. И где гарантия, что новых процессорах нет команд типа movsq и выше??
Спасибо.
Здравствуйте Eugene_White, Вы писали:
VDZ>>К сожалению, вы не правы — этот вариант в полтора раза медленне самого медленного MMX варианта... а до лидера (4 x movntq) надо быть более чем в три раза быстрее... VDZ>>этот вариант я отбросил сразу же, после анализа — чем больше копируется в регистры за один раз, тем больше производительность...
EW> Может я и погорячился насчет максимальной скорости (извините , но давайте рассмотрим Ваш первоначальный вариант. Насколько видно, очень много тратится впустую тактов выражениями EW> EW>l_p3: movq mm0, [esi + ecx*4] EW> movq [edi+ecx*4], mm0 EW> dec ecx EW> jnz l_p3,
EW>т.е. перенос через переменные. Это замедляет работу. Неужели не лучше будет доверить это процессору командой "rep" (почему ее Алекс Федотов "давит")? Она сама уменьшает есх и "лупит" — отсюда быстродействие. И где гарантия, что новых процессорах нет команд типа movsq и выше??
Дело в том, что при копировании больших объемов данных (больше, чем помещается в кэш первого уровня), количество тактов в инструкциях не имеет практически никакого значения. Решающее значение имеют операции, выполняемые на внешней шине процессора, так как она имеет ограниченную пропускную способность. В справочниках приводится количество тактов на инструкцию, когда операнды находятся в кэше первого уровня, когда же операнд приходится читать из памяти, это занимает на порядок больше времени.
Обычные команды записи, и movs в том числе, сначала считывают всю строку (32 байта) в кэш, а затем производят запись в кэш и (чуть позже) в память. Это разумно для работы с обычными переменными, но не для записи огромных массивов памяти, которые все равно не поместятся в кэш. Команды movntq, movntps и movntus не выполняют это бесполезное чтение и не засоряют кэши всех уровней ненужными данными, отсюда и заметный прирост в производительности.
Здравствуйте Eugene_White, Вы писали:
EW> Может я и погорячился насчет максимальной скорости (извините , но давайте рассмотрим Ваш первоначальный вариант. Насколько видно, очень много тратится впустую тактов выражениями EW> EW>l_p3: movq mm0, [esi + ecx*4] EW> movq [edi+ecx*4], mm0 EW> dec ecx EW> jnz l_p3,
EW>т.е. перенос через переменные. Это замедляет работу. Неужели не лучше будет доверить это процессору командой "rep" (почему ее Алекс Федотов "давит")? Она сама уменьшает есх и "лупит" — отсюда быстродействие. И где гарантия, что новых процессорах нет команд типа movsq и выше?? EW> Спасибо.
EW> EW
Не за что
вот тестовый примерчик — можно собрать и прогнать, а можно порассуждать логически:
void * p1 = malloc(4194304);
void * p2 = malloc(4194304);
// #1unsigned long *l1 = (unsigned long *)p1[0], *l2 = (unsigned long *)p2[0];
for (int i = 0; i < 1048576; i++)
{
*l2 = *l1;
l2++; l1++;
}
// #2double *d1 = (double*)p1[0], *d2 = (double)p2[0];
for (i = 0; i < 524288; i++)
{
*d2 = *d1;
d1++; d2++;
}
ну, как вы думаете, что будет быстрее?
#1 — 4 байта за один шаг
#2 — 8 байт за один шаг...
Спасибо всем отвечавшим
особенно Alex Fedotov'у
если кого заинтерисовало то. о чём тут вели разговор — тут лежит библиотека с некоторыми стандартнми функциями, реализованные через MMX...
о реализованных функциях написано тут... Все пожелания на счёт добавления чего-ньть мыльте мне
Здравствуйте VuDZ и Alex Fedotov.
Очень интересно почитать вашу переписку не являясь знатоком asm'a.
А ведь наверное первое, что делает ваша программа,
использующая asm — это определение типа процессора?
С этого и все начинающие программеры на asm'e начинают.
Подскажите пожалуйста, как точно узнать тип процессора программно?
Здравствуйте Речка, Вы писали:
Р>Здравствуйте VuDZ и Alex Fedotov. Р>Очень интересно почитать вашу переписку не являясь знатоком asm'a.
Р>А ведь наверное первое, что делает ваша программа, Р>использующая asm — это определение типа процессора? Р>С этого и все начинающие программеры на asm'e начинают.
Р>Подскажите пожалуйста, как точно узнать тип процессора программно?
ну на RTFM не будем-с посылать...
вот как я делал на наличие MMX & SSE проверки:
mov eax,0 // function 0 = manufacturer string
CPUID
// These tests could probably just check the 'ebx' part of the string,
// but the entire string is checked for completeness. Plus, this function
// should not be used in time-critical code, because the CPUID instruction
// serializes the processor. (That is, it flushes out the instruction pipeline.)
// Test for 'AuthenticAMD'
cmp ebx,'htuA'
jne short not_amd
cmp edx,'itne'
jne short not_amd
cmp ecx,'DMAc'
jne short not_amd
mov eax,MFG_AMD
jmp short next_test
Здравствуйте VuDZ, Вы писали:
VDZ>Здравствуйте VuDZ, Вы писали:
VDZ>Спасибо всем отвечавшим :) VDZ>особенно Alex Fedotov'у VDZ>если кого заинтерисовало то. о чём тут вели разговор — тут лежит библиотека с некоторыми стандартнми функциями, реализованные через MMX... VDZ>о реализованных функциях написано тут... Все пожелания на счёт добавления чего-ньть мыльте мне
Я конечно дико извеняюсь, но на VC6.0
команда prefetcht0 — не понимается, компилятор говорит что ошибка
может потому что у меня P-II?
Здравствуйте Gambler, Вы писали:
G>Я конечно дико извеняюсь, но на VC6.0 G>команда prefetcht0 — не понимается, компилятор говорит что ошибка G> может потому что у меня P-II?
Чтобы в inline assembler VC6.0 можно было использовать команды MMX и SSE, нужно скачать Visual C++ Processor Pack: http://msdn.microsoft.com/vstudio/downloads/ppack/download.asp (чуть больше 1 MB, но требует установленного Service Pack 4 или Service Pack 5).
Но работать на PII команда prefetcht0 не будет все равно: эта инструкция появилась только в PIII в составе SSE.
Здравствуйте Gambler, Вы писали:
G>Я конечно дико извеняюсь, но на VC6.0 G>команда prefetcht0 — не понимается, компилятор говорит что ошибка G> может потому что у меня P-II?
Для компиляции нужен processor pack
От процессора это не зависит...
Здравствуйте Alex Fedotov, Вы писали:
AF>Но работать на PII команда prefetcht0 не будет все равно: эта инструкция появилась только в PIII в составе SSE.
На счёт prefetcht0 — я зпускал пример с этой командой на 600Cel — всё работает... movntq — падает, а прекеширование работает... Честно говоря, с легка запутался — где MMX, MMX2, SSE MMX... — вся дока очень противоречива, а по интелу походить — руки не доходят
Жаль пока нет (у меня в компе) AtlnonXP — SSE вещь очень классная, по крайней мере чать команд весьма полезны — с постфиксом _q...
AF>В свое время я столкнулся с ситуацией, когда нужно было делать примерно следующее.
AF>WORD buffer1[N]; // DWORD-aligned AF>WORD buffer2[N]; // DWORD-aligned as well
AF>memcpy(buffer2 + 1, buffer1, (N — 1) * sizeof(WORD));
AF>Короче, you got the idea. Здесь получалось, что либо чтение будет DWORD-aligned, либо запись — данные так устроены. memcpy выбирала запись и проигрывала — когда я сделал свою версию, которая делала DWORD-aligned чтение, а писала как получится, она оказалась в среднем на 30% быстрее (PIII).
утилита от intel — показывает влияние выравнивания даных/наличие их в кэше
Здравствуйте, VuDZ, Вы писали:
VDZ>сейчвс этот код на 36% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить ? А то , только мне по голове
VDZ>Thanx for your attantion
где-то на АМД-шном сайте валяются с-шные либы, с асмом,
там есть оптимизированный под атлон memcpy, у куча других функций...
Здравствуйте, VuDZ, Вы писали:
VDZ>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы VDZ>Thanx for your attantion
А как насчёт использования для копирования память-память контроллера DMA?
Реализация будет посложнее и скорость, наверняка, поменьше
Зато можно ЦПУ в это время чем-нить другим загружать
Здравствуйте, Аноним, Вы писали:
А>А как насчёт использования для копирования память-память контроллера DMA? А>Реализация будет посложнее и скорость, наверняка, поменьше
Почему поменьше? По-моему как раньше так и сейчас — побольше. Вряд ли у современных DMA контроллеров высокая латентность буферов (скорее всего вообще отсутствует). Разве что они конвееризацию не понимают (тут точно не знаю, но скорее всего понимают). Выигрыш при копировании процессором будет только в том случае, когда часть из копируемых данных у него лежит в кэше (кэшах).
Другой вопрос как организовать грамотный (защищенный) интерфейс этого дела со стороны ОС ...
Re[3]: Копирование памяти
От:
Аноним
Дата:
14.02.03 10:16
Оценка:
Здравствуйте, Murr, Вы писали:
M>Почему поменьше? По-моему как раньше так и сейчас — побольше. Вряд ли у современных DMA контроллеров высокая латентность буферов (скорее всего вообще отсутствует). Разве что они конвееризацию не понимают (тут точно не знаю, но скорее всего понимают). Выигрыш при копировании процессором будет только в том случае, когда часть из копируемых данных у него лежит в кэше (кэшах).
M>Другой вопрос как организовать грамотный (защищенный) интерфейс этого дела со стороны ОС ...
Надо, видимо, писать драйвер с соответствующей функциональностью. Хотя как там этот контроллер надо мурыжить и чего из него можно выжать, я не представляю — никогда не сталкивался. Понятно, что практическая применимость этого мала, но вообще задачка интересная.
Здравствуйте, Аноним, Вы писали:
А>Надо, видимо, писать драйвер с соответствующей функциональностью.
Тут две проблемы:
1) несогласованность линейных и физических адресов (фрагментация).
2) некий продвинутый интерфейс блокировки пользовательских страничек в памяти.
A>Понятно, что практическая применимость этого мала, но вообще задачка интересная.
Возможно, это имеет некий смысл для кода ядра, который оперирует большими структурами внутри линейно-спроецированного на физическую память пространства ядра. (не сталкивался с такими)
Re[5]: Копирование памяти
От:
Аноним
Дата:
14.02.03 12:45
Оценка:
Здравствуйте, Murr, Вы писали:
M>Тут две проблемы: M>1) несогласованность линейных и физических адресов (фрагментация).
хех
интересно, а при трансферах размером в страницу выигрыш будет? если да, то и чёрт с ней, с фрагментацией
M>2) некий продвинутый интерфейс блокировки пользовательских страничек в памяти.
а я всегда думал, что некоторые драйвера делают DMA-пересылки прямо в "пользовательскую" память
и, соответственно, в ОСях такие механизмы блокировок предусмотрены
(повторюсь — я в этих вопросах дилетант, если не сказать хуже )
Здравствуйте, Аноним, Вы писали:
А>хех А>интересно, а при трансферах размером в страницу выигрыш будет? если да, то и чёрт с ней, с фрагментацией
Ну предположим, что частота системной шины 100 Мгц, процессора — 1000 Мгц.
Предположим, что каждые два такта системной шины, DMA выставляет либо запрос на запись в память, либо запрос на чтение памяти (2 такта — это, конечно, лажа. Но для подсчета порядка должно хватить). Шина данных — 64 бит (8 байт).
Потребуется 4096(байт)/8(байт/такт)*2(такта)=256 тактов шины. Т.е. 2560 тактов свободного процессорного времени (в это время процессор, естественно, не будет иметь доступа к шине — на ней будут проходить циклы слежения, инициированные чипсетом, для поддержки когерентности non-Modified строк кэша и ОЗУ).
А>а я всегда думал, что некоторые драйвера делают DMA-пересылки прямо в "пользовательскую" память А>и, соответственно, в ОСях такие механизмы блокировок предусмотрены
Ну да, в общем. Нужна примерно такая же схема и для DMA память-память. Блокировка диапазона ввода+блокировка диапазона вывода, DMA запрос, разблокировка.
Я писал:
M>Потребуется 4096(байт)/8(байт/такт)*2(такта)=256 тактов шины. Т.е. 2560 тактов свободного процессорного времени...
Ой как круто посчитал... Аж самому понравилось.
Должно быть 4096(байт)/8(байт/такт)*2(безразм.)=1024 тактов шины. Т.е. 10240 тактов процессорных часов.
Re[8]: Копирование памяти
От:
Аноним
Дата:
14.02.03 14:07
Оценка:
Здравствуйте, Murr, Вы писали:
M>Предположим, что каждые два такта системной шины, DMA выставляет либо запрос на запись в память, либо запрос на чтение памяти (2 такта — это, конечно, лажа. Но для подсчета порядка должно хватить). Шина данных — 64 бит (8 байт).
M>Потребуется 4096(байт)/8(байт/такт)*2(такта)=256 тактов шины. Т.е. 2560 тактов свободного процессорного времени (в это время процессор, естественно, не будет иметь доступа к шине — на ней будут проходить циклы слежения, инициированные чипсетом, для поддержки когерентности non-Modified строк кэша и ОЗУ).
Интересно. А где про все эти железячные тонкости почитать можно?
M>Ой как круто посчитал... Аж самому понравилось.
Правая ассоциативность рулит
M>Должно быть 4096(байт)/8(байт/такт)*2(безразм.)=1024 тактов шины. Т.е. 10240 тактов процессорных часов.
Я очень извиняюсь, но что означает эта волшебная цифра для нас, простых смертных?
Сколько аналогичных "попугаев" будет при копировании через регистры, и почему DMA быстрее.
И ещё очень интересно, каково при всём этом влияние кэша. Т.е. выгодно ли кэширование, или нет? И почему?
Здравствуйте, Аноним, Вы писали:
А>Правая ассоциативность рулит
Ага
А>Я очень извиняюсь, но что означает эта волшебная цифра для нас, простых смертных?
Ну по идее это означает, что можно выполнить 10240(+-)10240 ассемблерных инструкций за время копирования
А>Сколько аналогичных "попугаев" будет при копировании через регистры
Если без вытеснения кэша, то столько же. Если с вытеснением кэша (т.е. если начнем засорять кэш), то больше. Если часть данных уже находится в кэше (т.е. не нужно выполнять чтение из памяти), то меньше.
А>И ещё очень интересно, каково при всём этом влияние кэша. Т.е. выгодно ли кэширование, или нет? И почему?
Ну с точки зрения самого копирования (что для DMA, что для процессора, минуя кэш) — нет никакой разницы — что процессор, что DMA контроллер — будут формировать одни и те же шинные циклы: read->write->read->write или burst read->burst write->burst read->burst write. Если есть кэш, то он может как немного помогать (если он тем самым исключает фазу чтения, т.е. содержит копируемые данные), так и мешать (когда копируемые данные при чтении начинают вытеснять уже находящиеся в кэше).
Тонкости зависят от процессора и DMA контроллера. Но, для PC всё примерно так, как я написал (Pentium Manual, 8259A Manual на developer.intel.com).
Я писал:
M>Тонкости зависят от процессора и DMA контроллера. Но, для PC всё примерно так, как я написал (Pentium Manual, 8259A Manual на developer.intel.com).
То бишь 8237A... ( у кого что болит, тот о том и говорит )
Здравствуйте, assad, Вы писали:
A>Я могу ошибаться, но по-моему режим передачи по DMA A>память-память не работает вообще.
A>По крайней мере так было в эпоху 386,486, Pentium.
Да нет. Всегда работал. Может и были микросхемы, которые не поддерживали этот режим.
Хотя, там ведь все равно 24-битная адресация (т.е. первые 16 Мб), да и нельзя использовать 32 битные данные при копировании память-память (только при PC DMA)
Здравствуйте, Murr, Вы писали:
M>Здравствуйте, assad, Вы писали:
M>Да нет. Всегда работал. Может и были микросхемы, которые не поддерживали этот режим. M>Хотя, там ведь все равно 24-битная адресация (т.е. первые 16 Мб), да и нельзя использовать 32 битные данные при копировании память-память (только при PC DMA)
спорить не буду т.к. когда я пробовал это сделать под DOS лет 7 назад у меня ничего не получилось, а окончились мои попытки, когда я прочитал в какой-то авторитетной для меня книге (и даже по-моему не в одной), что режим передачи память — память зарезервирован.