На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> Копирование памяти
    Subj такой - надо с максимально озможной скоростью копировать данные из одного куска памяти в другой. Подошёл бы и memcpy(), но он очень медленный. Этот вопрос скорее по асму, но может кто ответит. Вот что есть сейчас:
    _asm
    {
    mov esi, p2;
    mov edi, p3;
    mov ecx, copy;
    shr ecx, 3;
    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;
    Дапоможите, хто чем может (желательно не теорией)
    ЗЫ prefetcht уже использовался - с ним только хуже
    mm0 + mm1 + mm2 + mm3 одновременно то же использовал.
    сейчвс этот код на 36\% быстрее. чем memcpy() на гиговом Атлоне, но может можно его ещё ускорить ?
    Спасибо
      Здесь нужно исходить из того, что...
      1. Читать/записывать память лучше всего по адресу, кратному 8 (для 64-битовой шины). А т.к. возможны разные комбинации адресов, в т.ч. когда первый адрес (исходный) кратен 8, а второй (куда записываем) - нет, возникает больше трудностей, поэтому я предлагаю выравнивать хотябы один адрес (наверное, если медленнее чтение, то первый, если запись, то второй). Но это ИМХО бессмысленно, если копируются небольшие участки памяти (несколько байт).
      2. Копировать лучше по 8 байт (а у тебя тут явная ошибка - не [...ecx*4], а [...ecx*8-8]). А 'sub ecx,1' здесь вообще не нужен.
      3. Размер блока может быть не кратен 8, так что твой вариант надо доработать!
      Могу сам написать процедуру вместе с выравниванием, только ты мне напиши:
      1. Что быстрее - чтение или запись?
      2. Манипуляции с MMX действительно быстрее, чем 'rep movsd'? MMX производит впечатление, что должен работать быстрее, но из-за jnz (а на это наверняка и уходит основное время) на самом деле может оказаться медленнее.
      3. Кстати, не ленись, попробуй копировать через FPU (загружать в ST(0) по 8 байт и записывать оттуда :)
      Только при тестировании проследи, чтобы адреса исходных блоков ВСЕГДА были кратны 8 (а лучше 16 :). И сделай второй тест, когда адреса на 1 больше кратного 8 значения. И не забудь, что при 'movq' делается 'shr ecx,3', а при 'rep movsd' - 'shr ecx,2'.
        1. Выравнивание везде 16 байт - это даёт ещё некий прирост в скорости
        2. movq mm0, [esi + ecx*4]; - movq и копирут 64бита сразу, а та да, ошибся, ecx*8 - но разница минимальна - эти данные уже лежали в кэше
        3. размер блока _всегда_ кратен 8, точнее 16
        ....
        копирование 1Mb for 50 times
        MMX - 171-181 ms
        rep movsd - 260 ms
        memcpy() - 250 ms
        походу, ничего быстрее не придумать...
          Почитай ещё доки об инструкциях MOVAPS/MOVUPS (для Pentium-III :) . Они записывают сразу 16 байт! Правда, [...ecx*16] уже не получится, но это вопрос номер 2...
          Только это уже не 'IA MMX', а 'IA MMX-2'
          На Athlon'е может не работать, но Athlon вроде тоже 128-битный (или я глючу?). Значит и для него что-то подобное есть... :)
          Удачи!!!
          ---------------------------------------------
          P.S. Кстати, попробовал я копирование через FPU (fild/fistp) на Pentium-II... Работает примерно так же, как и 'rep movsd'.
            самый быстрый вариант
            [code]
            {
            mov esi, p6;
            mov edi, p1;
            mov ecx, copy;
            shr ecx, 3; // devide on 8
            l_p3: movq mm0, [esi + ecx * 8-8]; // loading to cashe first32 bytes
            movq mm1, [esi + ecx * 8 - 16];
            movq mm2, [esi + ecx * 8 - 24];
            movq mm3, [esi + ecx * 8 - 32];
            // prefetcht0 [esi + ecx * 8 - 33]; // preload next 32 bytes
            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;
            }
              Ops....
              что то меня проглючило
              _asm
              {
              mov esi, p6;
              mov ecx, copy;
              prefetcht0 [esi + ecx - 32]; // preload next 32 bytes
              mov edi, p1;
              shr ecx, 3; // devide on 8
              l_p3: movq mm0, [esi + ecx * 8 - 8]; // loading to cashe first32 bytes
              movq mm1, [esi + ecx * 8 - 16];
              movq mm2, [esi + ecx * 8 - 24];
              movq mm3, [esi + ecx * 8 - 32];
              prefetcht0 [esi + ecx * 8 - 64]; // preload next 32 bytes
              movntq [edi + ecx * 8 - 8], mm0;
              movntq [edi + ecx * 8 - 16], mm1;
              movntq [edi + ecx * 8 - 24], mm2;
              movntq [edi + ecx * 8 - 32], mm3;
              sub ecx, 4;
              jnz l_p3;
              }
              _asm emms;
              http://vudz.by.ru/misc/asm_copy.htm
                Оригинально... Мог бы тогда уж все 8 регистров задействовать :)
                Раз уж всё-таки используешь prefetch0 (может, это глюк, но в моих доках без буквы 't', но это не важно), который для P-III и Athlon'ов, почитай всё-таки MOVAPS и MOVUPS и поищи аналоги для Athlon ;)
                  не надо сарказма
                  4 регистра используются по той простой причине, что только так происходит прирост в скорости, не большо (10-15\%) но есть...
                  А это всё, что можно сделать для атлона, не ХР - SSE MMX и всё...
                  скомпили тот файлик, на который я положил ссылку и посмотри сам на результаты - яот туды уже выкинул memcpy() и прочую фигню, но поймёшь в чём дело
                    в твоих доках глюки - prefetchtx, x=0,1,2,nt
                      Да. и ещё одно
                      если цикл короткий. типа 3-4 итерации. то лучше это дело записать сплошняком - работает быстрее, учитывая архитектуру процов...
                      по этому у меня 4 movq а посредине prefetcht0 - чтение 32 байт, прекэширование слудующих, запись...
                      когда запись заканчивается, данные уже в кеше.
                      а если сделать
                      movq mm0, []
                      prefetcht0 [esi]
                      movntq [edi], mm0
                      то так только хуже будет, с всязи с тем, что данные будут прекешировать без надобности по 3 раза
                      Всего хорошего
                      VuDZ
                        Я б с удовольствием (скомпилировал), но у меня VC нету как такового и комп у меня P-II :(
                        Кстати, я посмотрел - есть и prefetch, и prefetchT, и даже prefetchW оказывается :)
                        Слушай, может, ты знаешь, где можно достать доки по всем инструкциям (желательно до P-4 и с описанием :) ???
                        И доки типа TechHelp и Ralf Brown's..., но поновее и покруче, а то TechHelp'а новее шестого я что-то никак не найду :)
                        Короче, всё в этом духе... да (как в анекдоте) побольше-побольше... :)))
                          1. Процессоры PentiumIII, Athlon и другие...
                          2. Я заказывал в саппорте AMD и техническую документацию на СД. Скоро должна прийти
                          А так - берёш яндекс или что-то в этом роде, и начинаешь искать
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0360 ]   [ 15 queries used ]   [ Generated: 15.05.24, 07:27 GMT ]