Копирование памяти
От: VuDZ Россия  
Дата: 22.12.01 07:57
Оценка: 3 (1)
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++' — ПК
Re: Копирование памяти
От: Alex Fedotov США  
Дата: 22.12.01 09:55
Оценка:
Здравствуйте 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 байт?
Какой типичный размер копируемых данных?
-- Alex Fedotov
Re[2]: Копирование памяти
От: VuDZ Россия  
Дата: 22.12.01 11:04
Оценка:
AF>Аргументы выравнены на 8 байт?
AF>Какой типичный размер копируемых данных?

выравнивание 16ти байтовое
размер — от 64Kb до 16Mb, все размеры кратны 16.
Я думаю, что вообще-то это максимум, но может будут какие идеи?
Re: Копирование памяти
От: IT Россия linq2db.com
Дата: 22.12.01 14:39
Оценка:
Здравствуйте VuDZ, Вы писали:

VDZ>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный.


А ты не пробовал #pragma intrinsic(memcpy)? Может не придётся и с асмом заморачиваться.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Копирование памяти
От: VuDZ Россия  
Дата: 22.12.01 15:58
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте VuDZ, Вы писали:


VDZ>>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный.


IT>А ты не пробовал #pragma intrinsic(memcpy)? Может не придётся и с асмом заморачиваться.

Это увеличивает необходимое время, незначительно, но всё таки (781 vs 761 == 2.5%)... Видимо, ММХ единственный вариант ускорить копирование...
Re[3]: Копирование памяти
От: Alex Fedotov США  
Дата: 23.12.01 06:19
Оценка: 8 (2)
Здравствуйте VuDZ, Вы писали:

AF>>Аргументы выравнены на 8 байт?

AF>>Какой типичный размер копируемых данных?

VDZ>выравнивание 16ти байтовое

VDZ>размер — от 64Kb до 16Mb, все размеры кратны 16.
VDZ>Я думаю, что вообще-то это максимум, но может будут какие идеи?

В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.
-- Alex Fedotov
Re[2]: Копирование памяти
От: Alex Fedotov США  
Дата: 23.12.01 06:30
Оценка:
Здравствуйте 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

memcpy(buffer2 + 1, buffer1, (N — 1) * sizeof(WORD));

Короче, you got the idea. Здесь получалось, что либо чтение будет DWORD-aligned, либо запись — данные так устроены. memcpy выбирала запись и проигрывала — когда я сделал свою версию, которая делала DWORD-aligned чтение, а писала как получится, она оказалась в среднем на 30% быстрее (PIII).

Но к проблеме VuDZ это отношения не имеет — он говорит, у него данные выравнены.
-- Alex Fedotov
Re[4]: Копирование памяти
От: VuDZ Россия  
Дата: 23.12.01 08:18
Оценка: 27 (5)
Здравствуйте Alex Fedotov

AF>В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.


1. movntq — MMX команда
2. большое спасибо — скорость выросла очень сильно
_asm
{
mov esi, p1;
mov edi, p4;
mov ecx, copy;
shr ecx, 3; // devide on 8
l_p3:
movq mm0, [esi + ecx * 8]; // loading to cashe first32 bytes
movq mm1, [esi + ecx * 8 — 8];
movq mm2, [esi + ecx * 8 — 16];
movq mm3, [esi + ecx * 8 — 24];
prefetcht0 [esi + ecx * 8 — 33]; // preload next 32 bytes (prev)
movntq [edi + ecx * 8], mm0;
movntq [edi + ecx * 8 — 8], mm1;
movntq [edi + ecx * 8 — 16], mm2;
movntq [edi + ecx * 8 — 32], mm3;
sub ecx, 4;
jnz l_p3;
}

почти в два раза быстрее, чем было :)
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%
Re: Копирование памяти
От: VuDZ Россия  
Дата: 23.12.01 10:02
Оценка:
В общем вроде бы то, чего я добился — максимум-
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


тут можно посмотреть исходник
Re: Копирование памяти
От: Eugene_White Россия  
Дата: 23.12.01 11:32
Оценка: 1 (1)
Здравствуйте VuDZ.

Есть более рациональный способ. Через "rep movs(b,w,d)" — в зависимости от требуемого.
Пример.

mov ds:esi, p2 // откуда
mov es:edi, p3 // куда
mov ecx, size // сколько байт
rep movsb

если movsw, то size/2
если movsd — size/4
etc...

и больше ничего — скорость максимальная.

EW
Re[2]: Копирование памяти
От: VuDZ Россия  
Дата: 23.12.01 12:24
Оценка:
Здравствуйте 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) надо быть более чем в три раза быстрее...
этот вариант я отбросил сразу же, после анализа — чем больше копируется в регистры за один раз, тем больше производительность...
Re[5]: Копирование памяти
От: Alex Fedotov США  
Дата: 23.12.01 20:14
Оценка:
Здравствуйте VuDZ, Вы писали:

VDZ>Здравствуйте Alex Fedotov


AF>>В свое время я экспериментировал с этим на PIII и для больших блоков (> 1MB) несколько помог movntq, не знаю, есть ли аналоги на Athlon.


VDZ>1. movntq — MMX команда


Она оперирует с операндом в MMX-регистре, но появилась-то она как часть SSE. Вот, кстати, и ссылочка на эту тему нашлась:
http://developer.intel.com/software/idap/media/pdf/copy.pdf
-- Alex Fedotov
Re[6]: Копирование памяти
От: VuDZ Россия  
Дата: 24.12.01 02:19
Оценка:
Здравствуйте Alex Fedotov, Вы писали:


VDZ>>1. movntq — MMX команда


AF>Она оперирует с операндом в MMX-регистре, но появилась-то она как часть SSE. Вот, кстати, и ссылочка на эту тему нашлась:

AF>http://developer.intel.com/software/idap/media/pdf/copy.pdf

За ссылку спасибо.
Ьжет вы перепутали movntq с movntps — это SSЕ команда и котрая делает почти то же самое: запись 128 битного регистра минуя кеш.
А то у меня на атлоне нет поддерки SSE
Re[7]: Копирование памяти
От: Alex Fedotov США  
Дата: 24.12.01 05:25
Оценка:
Здравствуйте 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 порой пересекается с интеловскими весьма причудливым образом.
-- Alex Fedotov
Re[8]: Копирование памяти
От: VuDZ Россия  
Дата: 24.12.01 06:19
Оценка:
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...
Re[3]: Копирование памяти
От: Eugene_White Россия  
Дата: 24.12.01 12:45
Оценка:
Здравствуйте VuDZ, Вы писали:

VDZ>К сожалению, вы не правы — этот вариант в полтора раза медленне самого медленного MMX варианта... а до лидера (4 x movntq) надо быть более чем в три раза быстрее...

VDZ>этот вариант я отбросил сразу же, после анализа — чем больше копируется в регистры за один раз, тем больше производительность...

Может я и погорячился насчет максимальной скорости (извините :), но давайте рассмотрим Ваш первоначальный вариант. Насколько видно, очень много тратится впустую тактов выражениями

l_p3: movq mm0, [esi + ecx*4]
movq [edi+ecx*4], mm0
dec ecx
jnz l_p3,

т.е. перенос через переменные. Это замедляет работу. Неужели не лучше будет доверить это процессору командой "rep" (почему ее Алекс Федотов "давит")? Она сама уменьшает есх и "лупит" — отсюда быстродействие. И где гарантия, что новых процессорах нет команд типа movsq и выше??
Спасибо.

EW
Re[4]: Копирование памяти
От: Alex Fedotov США  
Дата: 24.12.01 12:55
Оценка:
Здравствуйте 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 не выполняют это бесполезное чтение и не засоряют кэши всех уровней ненужными данными, отсюда и заметный прирост в производительности.
-- Alex Fedotov
Re[4]: Копирование памяти
От: VuDZ Россия  
Дата: 24.12.01 13:30
Оценка:
Здравствуйте 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);
// #1
unsigned long *l1 = (unsigned long *)p1[0], *l2 = (unsigned long *)p2[0];
for (int i = 0; i < 1048576; i++)
{
  *l2 =  *l1;
  l2++; l1++;
}

// #2
double *d1 = (double*)p1[0], *d2 = (double)p2[0];
for (i = 0; i < 524288; i++)
{
  *d2 = *d1;
  d1++; d2++;
}

ну, как вы думаете, что будет быстрее?
#1 — 4 байта за один шаг
#2 — 8 байт за один шаг...

Vadim VuDZ
Re: Копирование памяти
От: VuDZ Россия  
Дата: 24.12.01 17:37
Оценка:
Здравствуйте VuDZ, Вы писали:

Спасибо всем отвечавшим
особенно Alex Fedotov'у
если кого заинтерисовало то. о чём тут вели разговор — тут лежит библиотека с некоторыми стандартнми функциями, реализованные через MMX...
о реализованных функциях написано тут... Все пожелания на счёт добавления чего-ньть мыльте мне
Re: Копирование памяти
От: Речка Россия  
Дата: 04.01.02 14:06
Оценка:
Здравствуйте VuDZ и Alex Fedotov.
Очень интересно почитать вашу переписку не являясь знатоком asm'a.

А ведь наверное первое, что делает ваша программа,
использующая asm — это определение типа процессора?
С этого и все начинающие программеры на asm'e начинают.

Подскажите пожалуйста, как точно узнать тип процессора программно?
Re[2]: Копирование памяти
От: VuDZ Россия  
Дата: 04.01.02 15:50
Оценка:
Здравствуйте Речка, Вы писали:

Р>Здравствуйте VuDZ и Alex Fedotov.

Р>Очень интересно почитать вашу переписку не являясь знатоком asm'a.

Р>А ведь наверное первое, что делает ваша программа,

Р>использующая asm — это определение типа процессора?
Р>С этого и все начинающие программеры на asm'e начинают.

Р>Подскажите пожалуйста, как точно узнать тип процессора программно?


ну на RTFM не будем-с посылать...
вот как я делал на наличие MMX & SSE проверки:

_IsMMX = false;
    _IsSSE = false;

    _asm
    {
        pusha;
        mov eax, 1;
        cpuid;
        bt edx, 32;
        jnc near _exitSSE;
        mov _IsSSE, 1;
_exitSSE:
        bt edx, 23;
        jnc near _exitMMX;
        mov _IsMMX, 1;
_exitMMX:
        popa;
    };


вот как у AMD:

 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


так что ищи описание CPUID
Re[2]: Копирование памяти
От: Gambler  
Дата: 06.01.02 20:52
Оценка:
Здравствуйте VuDZ, Вы писали:

VDZ>Здравствуйте VuDZ, Вы писали:


VDZ>Спасибо всем отвечавшим :)

VDZ>особенно Alex Fedotov'у
VDZ>если кого заинтерисовало то. о чём тут вели разговор — тут лежит библиотека с некоторыми стандартнми функциями, реализованные через MMX...
VDZ>о реализованных функциях написано тут... Все пожелания на счёт добавления чего-ньть мыльте мне

Я конечно дико извеняюсь, но на VC6.0
команда prefetcht0 — не понимается, компилятор говорит что ошибка
может потому что у меня P-II?

Спасибо
-------------------------------------------------------------------

Вызывает презедент к себе коров и говорит:
— Ну, что будем сдавать, молоко или мясо?
(с) Г. Явлинский TV6 — Герой дня (18.04.2002)
Re[3]: Копирование памяти
От: Alex Fedotov США  
Дата: 06.01.02 21:11
Оценка:
Здравствуйте 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.
-- Alex Fedotov
Re[3]: Копирование памяти
От: VuDZ Россия  
Дата: 06.01.02 21:11
Оценка:
Здравствуйте Gambler, Вы писали:

G>Я конечно дико извеняюсь, но на VC6.0

G>команда prefetcht0 — не понимается, компилятор говорит что ошибка
G> может потому что у меня P-II?

Для компиляции нужен processor pack
От процессора это не зависит...

успехов
Re[4]: Копирование памяти
От: VuDZ Россия  
Дата: 06.01.02 21:17
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>Но работать на PII команда prefetcht0 не будет все равно: эта инструкция появилась только в PIII в составе SSE.

На счёт prefetcht0 — я зпускал пример с этой командой на 600Cel — всё работает... movntq — падает, а прекеширование работает... Честно говоря, с легка запутался — где MMX, MMX2, SSE MMX... — вся дока очень противоречива, а по интелу походить — руки не доходят

Жаль пока нет (у меня в компе) AtlnonXP — SSE вещь очень классная, по крайней мере чать команд весьма полезны — с постфиксом _q...
Re[2]: Копирование памяти
От: VuDZ Россия  
Дата: 06.01.02 21:34
Оценка:
тут лежит реализация копирования памяти от АМД... Сделано просто супер...
Мда... а я то думал, что знаю асм
Re[3]: Копирование памяти
От: VuDZ Россия  
Дата: 06.01.02 22:02
Оценка:
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 — показывает влияние выравнивания даных/наличие их в кэше
Re: Копирование памяти
От: KostyaG  
Дата: 11.02.03 11:01
Оценка:
А если данные не выравнены
Имеет смысл использовать асм?
Re: Копирование памяти
От: plague Россия 177230800
Дата: 11.02.03 12:33
Оценка:
Здравствуйте, VuDZ, Вы писали:

VDZ>сейчвс этот код на 36% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить ? А то , только мне по голове


VDZ>Thanx for your attantion


где-то на АМД-шном сайте валяются с-шные либы, с асмом,
там есть оптимизированный под атлон memcpy, у куча других функций...

давно скачивал, должны быть...

помоему тут:

http://cdrom.amd.com/devconn/library.zip
Re: Копирование памяти
От: plague Россия 177230800
Дата: 11.02.03 19:40
Оценка:
Здравствуйте, VuDZ, Вы писали:

VDZ>Subj такой — надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы

VDZ>Thanx for your attantion

во, вспопмнил урл:

http://cdrom.amd.com/devconn/memcpy_amd.zip

там оптимайзенный memcpy...
Re: Копирование памяти
От: Аноним  
Дата: 14.02.03 01:06
Оценка:
А как насчёт использования для копирования память-память контроллера DMA?
Реализация будет посложнее и скорость, наверняка, поменьше
Зато можно ЦПУ в это время чем-нить другим загружать
Re[2]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 09:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А как насчёт использования для копирования память-память контроллера DMA?

А>Реализация будет посложнее и скорость, наверняка, поменьше
Почему поменьше? По-моему как раньше так и сейчас — побольше. Вряд ли у современных DMA контроллеров высокая латентность буферов (скорее всего вообще отсутствует). Разве что они конвееризацию не понимают (тут точно не знаю, но скорее всего понимают). Выигрыш при копировании процессором будет только в том случае, когда часть из копируемых данных у него лежит в кэше (кэшах).

Другой вопрос как организовать грамотный (защищенный) интерфейс этого дела со стороны ОС ...
Re[3]: Копирование памяти
От: Аноним  
Дата: 14.02.03 10:16
Оценка:
Здравствуйте, Murr, Вы писали:


M>Почему поменьше? По-моему как раньше так и сейчас — побольше. Вряд ли у современных DMA контроллеров высокая латентность буферов (скорее всего вообще отсутствует). Разве что они конвееризацию не понимают (тут точно не знаю, но скорее всего понимают). Выигрыш при копировании процессором будет только в том случае, когда часть из копируемых данных у него лежит в кэше (кэшах).


M>Другой вопрос как организовать грамотный (защищенный) интерфейс этого дела со стороны ОС ...


Надо, видимо, писать драйвер с соответствующей функциональностью. Хотя как там этот контроллер надо мурыжить и чего из него можно выжать, я не представляю — никогда не сталкивался. Понятно, что практическая применимость этого мала, но вообще задачка интересная.
Re[4]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 10:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Надо, видимо, писать драйвер с соответствующей функциональностью.

Тут две проблемы:
1) несогласованность линейных и физических адресов (фрагментация).
2) некий продвинутый интерфейс блокировки пользовательских страничек в памяти.

A>Понятно, что практическая применимость этого мала, но вообще задачка интересная.

Возможно, это имеет некий смысл для кода ядра, который оперирует большими структурами внутри линейно-спроецированного на физическую память пространства ядра. (не сталкивался с такими)
Re[5]: Копирование памяти
От: Аноним  
Дата: 14.02.03 12:45
Оценка:
Здравствуйте, Murr, Вы писали:

M>Тут две проблемы:

M>1) несогласованность линейных и физических адресов (фрагментация).

хех
интересно, а при трансферах размером в страницу выигрыш будет? если да, то и чёрт с ней, с фрагментацией

M>2) некий продвинутый интерфейс блокировки пользовательских страничек в памяти.


а я всегда думал, что некоторые драйвера делают DMA-пересылки прямо в "пользовательскую" память
и, соответственно, в ОСях такие механизмы блокировок предусмотрены
(повторюсь — я в этих вопросах дилетант, если не сказать хуже )
Re[6]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 13:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>хех

А>интересно, а при трансферах размером в страницу выигрыш будет? если да, то и чёрт с ней, с фрагментацией
Ну предположим, что частота системной шины 100 Мгц, процессора — 1000 Мгц.
Предположим, что каждые два такта системной шины, DMA выставляет либо запрос на запись в память, либо запрос на чтение памяти (2 такта — это, конечно, лажа. Но для подсчета порядка должно хватить). Шина данных — 64 бит (8 байт).

Потребуется 4096(байт)/8(байт/такт)*2(такта)=256 тактов шины. Т.е. 2560 тактов свободного процессорного времени (в это время процессор, естественно, не будет иметь доступа к шине — на ней будут проходить циклы слежения, инициированные чипсетом, для поддержки когерентности non-Modified строк кэша и ОЗУ).

А>а я всегда думал, что некоторые драйвера делают DMA-пересылки прямо в "пользовательскую" память

А>и, соответственно, в ОСях такие механизмы блокировок предусмотрены
Ну да, в общем. Нужна примерно такая же схема и для DMA память-память. Блокировка диапазона ввода+блокировка диапазона вывода, DMA запрос, разблокировка.
Re[7]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 13:11
Оценка:
Я писал:

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 быстрее.

И ещё очень интересно, каково при всём этом влияние кэша. Т.е. выгодно ли кэширование, или нет? И почему?
Re[9]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 14:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Правая ассоциативность рулит

Ага

А>Я очень извиняюсь, но что означает эта волшебная цифра для нас, простых смертных?


Ну по идее это означает, что можно выполнить 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).
Re[10]: Копирование памяти
От: Murr Россия  
Дата: 14.02.03 14:31
Оценка:
Я писал:

M>Тонкости зависят от процессора и DMA контроллера. Но, для PC всё примерно так, как я написал (Pentium Manual, 8259A Manual на developer.intel.com).

То бишь 8237A... ( у кого что болит, тот о том и говорит )
Re[11]: Копирование памяти
От: assad Россия  
Дата: 19.02.03 07:32
Оценка:
Я могу ошибаться, но по-моему режим передачи по DMA
память-память не работает вообще.

По крайней мере так было в эпоху 386,486, Pentium.
... << RSDN@Home 1.0 beta 5 >>
Re[12]: Копирование памяти
От: Murr Россия  
Дата: 19.02.03 12:59
Оценка:
Здравствуйте, assad, Вы писали:

A>Я могу ошибаться, но по-моему режим передачи по DMA

A>память-память не работает вообще.

A>По крайней мере так было в эпоху 386,486, Pentium.


Да нет. Всегда работал. Может и были микросхемы, которые не поддерживали этот режим.
Хотя, там ведь все равно 24-битная адресация (т.е. первые 16 Мб), да и нельзя использовать 32 битные данные при копировании память-память (только при PC DMA)

Так что... ничего не получится...
Re[13]: Копирование памяти
От: assad Россия  
Дата: 21.02.03 08:32
Оценка:
Здравствуйте, Murr, Вы писали:

M>Здравствуйте, assad, Вы писали:


M>Да нет. Всегда работал. Может и были микросхемы, которые не поддерживали этот режим.

M>Хотя, там ведь все равно 24-битная адресация (т.е. первые 16 Мб), да и нельзя использовать 32 битные данные при копировании память-память (только при PC DMA)

спорить не буду т.к. когда я пробовал это сделать под DOS лет 7 назад у меня ничего не получилось, а окончились мои попытки, когда я прочитал в какой-то авторитетной для меня книге (и даже по-моему не в одной), что режим передачи память — память зарезервирован.

Так, что если ошибся — извините.
... << RSDN@Home 1.0 beta 5 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.