Форум программистов, компьютерный форум, киберфорум
Assembler: MASM64, х64/long mode
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/40: Рейтинг темы: голосов - 40, средняя оценка - 4.95
E=m*c^2
 Аватар для K_ILYA_V
160 / 47 / 10
Регистрация: 04.02.2019
Сообщений: 263
Записей в блоге: 5
MASM

Использование 32-разрядных инструкций push/pop в режиме x64

02.04.2020, 14:55. Показов 9680. Ответов 46

Студворк — интернет-сервис помощи студентам
Доброго времени!
Существует ли способ написать в тексте ассемблера команду в машинных кодах?

я хочу вставить в текст masm64 32-битные команды. я смотрю через дебагер и вижу что компилятор спокойно использует 32-битные и даже 16-битные команды там где считает это нужным, тоесть принципиального запрета на это нет, но он несогласен использовать 32-битные команды JMP r32/ POP r32 / PUSH r32.

я хотел бы вставить нужные мне команды в текст напрямую
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.04.2020, 14:55
Ответы с готовыми решениями:

Сделать так чтобы если вводится push выполнялась функция push, если pop то pop
Помогите пожалуйста с данным вопросом: например у меня есть список и несколько возможных с ним операций (например push - добавить элемент...

Использование #pragma pack(push,1)... pack(pop)
Добрый день, товарищи. Задался вопросом о записи в файл структур данных, читал читал в интернете много интересного. Наткнулся на...

Push, Pop
Вот такое задание: F=Ʃ от 1 до 5 f (Ai) A1=2 Ai+1=Ai+2 Ai=(3*A)+(C/D). Нужно записать эту формулу в ассемблере с помощью Push, Pop...

46
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
05.04.2020, 08:17
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Jin X Посмотреть сообщение
Скажем, процессор ещё не записал данные, а какой-нибудь DMA хочет их прочитать.
..это называют "поддержкой когерентности" (согласованность данных в кэш и озу). Тема мутная и кое-чем делится на этот счёт Крис в своей "Техника оптимизации программ". Если коротко (и верить М.Гуку), то проц решает проблему так..

Для согласования данных кэша и ОЗУ, процессор отрабатывает циклы-слежения (snoop-cycle). В этих циклах, происходящих при обращении к ОЗУ внешних абонентов, проц определяет присутствие затребованной ими области, в своём кэше. Если область у него отображается, дальнейшие действия зависят от типа обращения. Если вн.абонент пытается записать что-то в ОЗУ, то процессор уничтожает соответствующую линейку из своего кэша. Если-же вн.абонент читает - то кэш-линейка выгружается в ОЗУ, прежде чем клиент выполнит реальное считывание. Более того, в таких случаях современные процессоры могут вообще не записывать грязные линейки в ОЗУ, а передавать их сразу абонентам - выгрузка в ОЗУ произойдёт позже.

Цитата Сообщение от Ethereal Посмотреть сообщение
Сигнал DQM я нашел у SDRAM, но ни разу у DDR-2. А маскирование отдельных байт это линии DM0..DM7 у DDR-2 и это не один пин (вывод), а восемь.
DQM и DM - это синонимы: DQ - данные, DQM - маска данных.
и правильно.. он появился сразу с приходом синхронной памяти.
я не говорил, что это 1-пин - из контролёра маска выходит 8-битной шиной, по биту на каждый чип (что демонстрирует рисунок битами 7:0):
Миниатюры
Использование 32-разрядных инструкций push/pop в режиме x64  
2
E=m*c^2
 Аватар для K_ILYA_V
160 / 47 / 10
Регистрация: 04.02.2019
Сообщений: 263
Записей в блоге: 5
05.04.2020, 18:07  [ТС]
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение

Не по теме:

Хотя у процессора 14 регистров общего назначения по 64 бита - но, видимо, и им конец пришёл

регистры закончились уже давно.

Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
Т.е. нужно сразу сказать, что это плохая идея использовать 8-16-32 разрядные переменные в режиме x64? И рекомендовать ТС больше так не делать?
вы не поняли сути идеи вот пример работающего кода:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    jmp m3  
        m1: mov [edi],edx
            shr ebp,1
            setc bl
            lea rdi,[rdi + rbx * 4]
            add rdx,4
            ret
        m2: rept 8
                call m1
            endm
            ret
        m3: vmovmskps ebp,ymm2
            call m2
            ror rdi,20h
            ror rdx,20h
            vmovmskps ebp,ymm4
            call m2
            ror rdi,20h
            ror rdx,20h
            add regdata0,vectorymmByte
        dec ecx
в каждом из регистров rdi / rbx лежит два значения и один и тот же код обрабатывает два потока данных
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
06.04.2020, 02:14
Цитата Сообщение от R71MT Посмотреть сообщение
Как правило записываемые данные тоже в руках проца, он скидывает эту линейку в "буфер отложенной записи" кэша-L3, и ставит ей флаг "Dirty" (грязная) - это алгоритм политики Write-Back. Если-же политика Write-Through (сквозная запись), то линейка не попадает в отложенный буфер и сразу выставляется на шину-памяти.
А от чего зависит выбор политики? И может ли процессор выполнять запись в фоновом режиме? Т.е. код передал данные процу (записал в нужные байты кэша или в какое-то временное хранилище) и не ждёт чтения всей линии в кэш. Ведь коду ничего обратно получать не нужно.

Цитата Сообщение от R71MT Посмотреть сообщение
Только делается это задолго до того, как EIP дойдёт до соответствующей инструкции типа stosb. Поэтому я и говорю, что данные уже у проца.
Ну проц же не всегда может предугадать, наступит этот stosb или нет (и когда).

Цитата Сообщение от R71MT Посмотреть сообщение
Если логика обнаруживает, что код планирует записать всего 1 байт, она может отключить пакетный режим в циклах записи, в результате чего на шину попадёт не вся линейка из L3, а только 8-байт (разрядность шины) - меньше не поддерживается. Теперь из этих восьми байт через пин DQM маскируются ненужные. Такие операции занимают много времени, поскольку контролёр отбросит эти 8-байт в самый хвост очереди, установив приоритет пакетным циклам.
И тут же снова тот же вопрос: это же может происходить в фоновом режиме?

Цитата Сообщение от R71MT Посмотреть сообщение
Начиная с DDR-2, у его чипов появился специальный пин DQM или "Data-Mask". Этот пин позволяет маскировать отдельные байты в 64-байтной линейке. К примеру если нужно записать в ОЗУ младшее слово из 64-х, то контролёр замаскирует все, кроме первых\двух.
Ты же говоришь, что он можно записать минимум 8 байт. И какая нам разница – будет он писать всю линейку или только часть? Это же взаимоотношения процессора и памяти. На что это влияет с точки зрения программиста?

Добавлено через 20 минут
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
не получит ли программа резкое замедление из-за получения режима чтение-модификация-запись вместо ожидаемой записи
Чтение всегда идёт порциями по 64 байта, заполняя всю линию кэша. Т.к. программа почти никогда не может читать/писать данные только по 64 байта (может только инструкциями AVX-512), то какая разница – 1 байт она запишет, 4 или 8, если всё равно данных в кэше нет и придётся их читать?

Другой момент, что читать 8 раз по 1 байту – это гораздо медленнее (даже если данные будут в кэше после прочтения первого байта, а они там будут, если чтение все 8 раз будет происходить в пределах 1 линии кэша), чем 1 раз по 8 байт. Соответственно, 2 раза по 4 байта будет медленнее, чем 1 раз по 8 байт.

Программа может (на некоторых процессорах) получить замедление, если данные не будут выравнены по ближайшей (в сторону увеличения) границе степени двойки размера читаемых/записываемых данных. Т.е. для qword - по 8 байтам, для dword - по 4 байтам, tbyte - по 16 байтам и т.д. Особенно, если будет пересечение границы линии кэша. В SSE/AVX есть даже разные инструкции для чтения/записи данных по выравненному адресу и по невыравненному (к примеру, movaps/movups, movdqa/movdqu).

Кроме того, особо критически важные в плане скорости исполнения многократно повторяемые блоки кода (функции, циклы) должны быть выравнены по границе 16 байт. Однако выигрыш в скорости от выравнивания в большинстве случаев минимален, поэтому делать так есть смысл только в особо критических случаях.

Если написать movnti [x],eax (запись в память, минуя кэш), код выполнится очень быстро, а если:
Assembler
1
2
movnti [x],eax
mov edx,[x]
то задержка будет весьма и весьма существенной. Это снова наводит на мысль о фоновой записи. Хотя, неисключено, что при задействовании кэша это работает немного иначе.

Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
Имитацию push/pop r16 можно реализовать - а именно этого хочет топикстартер - таким образом
push/pop r16 имитировать не нужно, это и так можно сделать, проблема у ТС с r32. Но лично я не очень понимаю смысла сей операции. Для чего это нужно?

Цитата Сообщение от K_ILYA_V Посмотреть сообщение
в каждом из регистров rdi / rbx лежит два значения и один и тот же код обрабатывает два потока данных
Иии? Мне лично не очень понятен ваш код и что вы хотите сделать. Объясните лучше словами суть. И зачем вам push'ить 32-битные регистры в 64-битном коде?

Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
у процессора 14 регистров общего назначения по 64 бита
Почему 14? Вместе с RSP (который тоже считается РОН) – 16, но и без него 15.

Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
Мануалы Intel хороши в отрыве от ОС, но вот ОС накладывает ограничения в возможность выбора стратегии кэширования.
В мануалах Intel описана работа процессора, которая не зависит от ОС. Это основа всего. Конечно, какие-то возможности недоступны юзеру, но никакого секрета в этом нет. В частности, инструкции movnt*, prefetch* и clflush* доступны юзеру, оптимизация организации данных, кода и циклов – тоже. В чём же тогда ограничения?
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
06.04.2020, 06:45
Цитата Сообщение от Jin X Посмотреть сообщение
А от чего зависит выбор политики? И может ли процессор выполнять запись в фоновом режиме?
В лицензионных Win политика строго определена - L1 всегда придерживается сквозной записи WT, а L2 отложеной WB. Если есть L3, то L2 тоже может отфутболивать линейки дальше по WT. То-есть по иерархии грязная работа достаётся младшему. WT подразумевает запись и в свой кэш, и в следующий (обеспечивая когерентность на своём уровне).. а чем этот следующий будет заниматься - ему по-барабану. Можно запустить шпиона типа Aida (у меня PC-Wizard) и убедиться в этом:



А на счёт выгрузки в фоне - вполне возможно. Только реальной записью линеек в память процессор не занимается, а озадачивает этим как-минимум контроллёр шины BIU (Bus-Interface-Unit), который имеет свой FIFO-буфер. Поскольку шина-памяти одна (в двуканальном две), BIU в любом случае будет дожидаться её освобождения. У каждого ядра свой L1, хотя общий - последний в иерархии. Поэтому если соседнее ядро свободно, то выгрузить чужие данные из общего кэша по WB может и оно - тогда получится типа в фоне.

Цитата Сообщение от Jin X Посмотреть сообщение
Ну проц же не всегда может предугадать, наступит этот stosb или нет (и когда).
Speculative (упреждающий) - выполнение работы до подтверждения необходимости её результатов. В конвейерных процессорах - загрузка и исполнение наиболее вероятных команд и данных. Упреждение применяется, чтобы не ступорить часть конвейера в ожидании точного результата, когда нужные для работы текущей стадии данные или коды, будут получены лишь через несколько тактов. Проверка верности упреждения для команд происходит при отставке их из конвейера, а для данных возможна и ранее. Упреждение для команд применяется при предсказании ветвлений и внеочерёдном исполнении, а для данных - при предзагрузке и внеочерёдном доступе к памяти.
Цитата Сообщение от Jin X Посмотреть сообщение
Ты же говоришь, что он можно записать минимум 8 байт. И какая нам разница – будет он писать всю линейку или только часть? Это же взаимоотношения процессора и памяти. На что это влияет с точки зрения программиста?
..не записать, а выставить на шину. Дальше, кол-во записываемых байт определяется масками DQM. Просто отключается пакетный режим и счётчик повторений записи Burst-Length сбрасывается в нуль.

В принципе разницы нет, и вообще не понимаю зачем нужны эти биты-маски. Перед записью, контролёр открывает всю строку банка памяти, и все байты из этой строки сваливаются в буфер Sense-AMP, куда и производится реальная запись данных - в DRAM-матрицу чипов записанные данные попадают уже из Sense-AMP. Одна отрытая строка физ.памяти равна одной странице вирт.памяти, а это мин.4 Кб. Соответственно можно заполнить записью хоть всю открытую страницу, и такой\страничный режим тоже существует - итого их три: страничный, пакетный и обычный.
2
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
06.04.2020, 12:13
Цитата Сообщение от R71MT Посмотреть сообщение
В лицензионных Win политика строго определена - L1 всегда придерживается сквозной записи WT, а L2 отложеной WB.
Погоди, а L1 WT проваливается куда? В L2 или сразу в память? Это же медленно должно быть в любом случае (или это делается, опять же, в фоне)?
У меня AIDA64 почему-то не показывает политику, а PC-Wizard не работает в 10-ке

Цитата Сообщение от R71MT Посмотреть сообщение
тогда получится типа в фоне
Не, меня интересует в фоне относительно выполняемой инструкции. Т.е. чтобы инструкция не ждала, когда произойдёт выгрузка. Что там внутри происходит – это другой вопрос.

Цитата Сообщение от R71MT Посмотреть сообщение
Speculative (упреждающий) - выполнение работы до подтверждения необходимости её результатов.
Погоди. Чтение из памяти – это порядка 100 тактов (как пишет А.Фог). Это ж сколько (десятков) операций нужно спекулятивно выполнить, чтобы не было задержки?

Добавлено через 14 минут
И второй интересный момент. Запускаю я тест скорости. Обычная память – 17 Гб/с, L1 – 460 Гб/с. Т.е. за один такт читается 4,5 байта из обычной памяти и 124 байта из L1 (при тактовой частоте 3700 МГц). Допустим, что за одну операцию одно ядро читает 32 байта (YMM) и работает 4 ядра, итого 128 байт. Т.о. при чтении из обычной памяти 1 инструкция (причём, параллельно на каждом из 4-х ядер) выполняется примерно за 28 тактов, а при чтении из L1 – за 1. Про L1 понятно, вроде всё логично. Но из обычной памяти должно производиться параллельное чтение сразу нескольких участков памяти, ведь 28 тактов – это на 4 ядра, а на одно 7, т.е. на 100 тактов выполняется ≈ 14-16 операций чтения по 32 байта или по 7-8 операций по 64 байта, т.е. получается, что они должны выполняться параллельно (с упреждением, т.е. спекулятивно, опять же). Но канал памяти же один (ну или два изредка). Или читается сразу, скажем, целая страница (в какой-нибудь L3)? Как это всё работает?
2
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
06.04.2020, 17:15
Цитата Сообщение от R71MT Посмотреть сообщение
В принципе разницы нет, и вообще не понимаю зачем нужны эти биты-маски.
Так вроде бы только что обсуждали. Биты-маски нужны чтобы вместо "чтение-модификация-запись" можно было бы сделать просто "запись". Разница в том, что есть возможность исключить операцию "чтение".

Добавлено через 3 минуты
Цитата Сообщение от R71MT Посмотреть сообщение
Перед записью, контролёр открывает всю строку банка памяти, и все байты из этой строки сваливаются в буфер Sense-AMP, куда и производится реальная запись данных - в DRAM-матрицу чипов записанные данные попадают уже из Sense-AMP. Одна отрытая строка физ.памяти равна одной странице вирт.памяти, а это мин.4 Кб.
Ну и вот зачем читать целых 4 килобайта из DRAM когда нужно записать один байт ? Неужели в компьютере всегда такая чушь делается ? Вот ни разу не поверю.

Добавлено через 22 минуты
Цитата Сообщение от Jin X Посмотреть сообщение
Погоди. Чтение из памяти – это порядка 100 тактов (как пишет А.Фог). Это ж сколько (десятков) операций нужно спекулятивно выполнить, чтобы не было задержки?
Да хоть десять раз упреждающее исполнение, все равно память - самое узкое место. А значит все равно будет ситуация когда процессор и рад бы чего-нибудь еще упреждающе предвыполнить, ан нету. Еще из памяти не подсосало. Которая тут-же перейдет в ситуацию - рад бы чего-нибудь просто выполнить, ан и этого нету.

Добавлено через 4 минуты
Цитата Сообщение от R71MT Посмотреть сообщение
Поэтому я и говорю, что данные уже у проца.
Раз подсос из памяти более медленный чем исполнение кода процессором постоянно должна повторяться ситуация когда у процессора код есть, а данных к нему еще нет и нужно подождать, покурить. Вот я о чем. Такая ситуация неизбежно должна динамически возникать.

Добавлено через 6 минут
З.Ы. По моему построение процессора - это набор пребанальнейших идей и когда их понял нет смысла копаться в деталях. Все равно кроме тех-же самых идей ничего выкопано не будет.
2
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
06.04.2020, 18:49
Цитата Сообщение от Ethereal Посмотреть сообщение
Так вроде бы только что обсуждали. Биты-маски нужны чтобы вместо "чтение-модификация-запись" можно было бы сделать просто "запись". Разница в том, что есть возможность исключить операцию "чтение".
Я честно говоря, не очень понимаю, как процессор сможет определить тот факт, что данные 8 байт (если там минимум порциями по 8 можно писать) в ближайшее время не понадобятся, поэтому их не надо читать и кэшировать. Ну заглянет он на 10-20 (или сколько там) инструкций вперёд и всё.

Цитата Сообщение от Ethereal Посмотреть сообщение
Которая тут-же перейдет в ситуацию - рад бы чего-нибудь просто выполнить, ан и этого нету.
Вот на этом-то HT и зиждется, судя по всему, в первую очередь
Понятно, что не только на этом, но с другой стороны, раз прирост такой маленький, как пишут (30% в лучшем случае, а обычно и того меньше: 5-10-15%), значит всё-таки спекуляция и внеочерёдка более или менее неплохо работают (и тем более, раз по 4 SMT на ядро в юзерских процах не делают). Хотя ещё, наверное, среднестатистический код всё же довольно-таки редко, работая с памятью, попадает в ситуации промахов кэша. В целом, это логично, т.к. бОльшая часть работы с памятью осуществляется либо в стеке, либо в одной и той же области. Но ещё такой малый прирост может быть, если спекулятивно выполненный код выбрасывается за ненадобностью в довольно большом объёме (т.е. процессор много шпарит вхолостую). Я так думаю ©. А вот это, кстати, интересно: какова статистика по этому показателю (сколько спекулятивно выполненного кода улетает в трубу)?
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
06.04.2020, 22:52
Цитата Сообщение от Jin X Посмотреть сообщение
а L1 WT проваливается куда? В L2 или сразу в память?
При любой политике, кэши передают данные только друг-другу как эстафетную палочку, обходных путей там нет, т.е. L1 не сможет напрямую общаться с L3. Проц отправил линейку по WT и считает-что она уже в ОЗУ, хотя по факту запись зависит от настроения последнего кэша (при кэшируемых операциях).
Цитата Сообщение от Jin X Посмотреть сообщение
У меня AIDA64 почему-то не показывает политику
попробуй сбросить дамп в лог.. обычно в нём больше инфы, чем в окне.
Цитата Сообщение от Jin X Посмотреть сообщение
Это ж сколько (десятков) операций нужно спекулятивно выполнить, чтобы не было задержки?
..ну до килобайта проц точно подкачивает на старте в свой кэш, а дальше уже по-обстоятельствам видимо.
Цитата Сообщение от Ethereal Посмотреть сообщение
Ну и вот зачем читать целых 4 килобайта из DRAM когда нужно записать один байт ? Неужели в компьютере всегда такая чушь делается ? Вот ни разу не поверю.
..так устроена запоминающая матрица динамической памяти.
Шина-адреса у неё-же не 64, а 15-битная и называется МА - мультиплексный адрес. Проц выставляет на шину линейный, а контролёр преобразует его в двумерный DRAM-адрес строка\столбец. Сколько отводится под строку и сколько под столбец, можно узнать из даташита на память:



Здесь видно, что под Row выделяется 14-бит, а под столбец 10. Выходит эта матрица состоит из: 16К строк (высота), и 1К столбцов (длина). Это адресация одного банка памяти (1К Page Size per Bank), а всего у DDR3 их 8. Три бита BA[0:2] представляют собой 3-старших бита строки так, что всего реальных строк в матрице получается уже не 16К, а х8=128К. Кол-во столбцов при этом остаётся прежним 1К, и в каждом хранится байт - это и есть "открытая страница" (в данном случае) размером 1-Кбайт. У DDR2 страницы были 4К-байтные, зато строк было меньше.

Поскольку строка идёт по всей 10-битной ширине матрицы, то контролёр физически не может открыть её половину - приходится открывать всю, в результате чего отпираются затворы всех ячеек памяти (которые висят на этой строке) и 1К инфы сваливается в буфер Sense-AMP. Только теперь контролёр посылает строб CAS#, и следом адрес столбца.

В не зависимости чтение это или запись, по заданному адресу столбца, байты перезаписываются именно в буфере Sense-AMP, а уже позже восстанавливаются на прежнее место в матрицу. У каждого банка свой усилитель SAMP, поэтому контролёры могут держать открытыми сразу несколько страниц с одинаковым адресом, но в разных банках, или-же бегущими огнями чередовать доступ к ним в режиме "Interleaving". Это позволяет параллельно читать одну строку, и регенерировать другую.
1
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
07.04.2020, 10:39
Цитата Сообщение от R71MT Посмотреть сообщение
В не зависимости чтение это или запись, по заданному адресу столбца, байты перезаписываются именно в буфере Sense-AMP, а уже позже восстанавливаются на прежнее место в матрицу.
Т.е. всё-таки по 8 байт можно читать/писать (или даже по 1 в зависимости от DQM)?
Замороченная система, конечно.

Что скажешь всё-таки про всё вот это безобразие:
Цитата Сообщение от Jin X Посмотреть сообщение
Не, меня интересует в фоне относительно выполняемой инструкции. Т.е. чтобы инструкция не ждала, когда произойдёт выгрузка. Что там внутри происходит – это другой вопрос.
Цитата Сообщение от Jin X Посмотреть сообщение
И второй интересный момент. Запускаю я тест скорости. Обычная память – 17 Гб/с, L1 – 460 Гб/с. Т.е. за один такт читается 4,5 байта из обычной памяти и 124 байта из L1 (при тактовой частоте 3700 МГц). Допустим, что за одну операцию одно ядро читает 32 байта (YMM) и работает 4 ядра, итого 128 байт. Т.о. при чтении из обычной памяти 1 инструкция (причём, параллельно на каждом из 4-х ядер) выполняется примерно за 28 тактов, а при чтении из L1 – за 1. Про L1 понятно, вроде всё логично. Но из обычной памяти должно производиться параллельное чтение сразу нескольких участков памяти, ведь 28 тактов – это на 4 ядра, а на одно 7, т.е. на 100 тактов выполняется ≈ 14-16 операций чтения по 32 байта или по 7-8 операций по 64 байта, т.е. получается, что они должны выполняться параллельно (с упреждением, т.е. спекулятивно, опять же). Но канал памяти же один (ну или два изредка). Или читается сразу, скажем, целая страница (в какой-нибудь L3)? Как это всё работает?
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
07.04.2020, 15:05
Цитата Сообщение от Jin X Посмотреть сообщение
Замороченная система, конечно.
..почему-же?
Инженерам нужно было придумать или две отдельные системы на запись и чтение, или-же сделать одну универсальную. Если с записью в DRAM-матрицу всё прозрачно, то чтение деструктивно по своей природе, т.к. при этом накопительные кондёры всей строки (страницы) разряжаются. Поэтому она и сбрасывается в усилитель-буфер Sense-AMP, чтобы сохранить информацию во-всей строке. Если имеются другие варианты, то думаю инженеры были-бы рады их услышать.

Цитата Сообщение от Jin X Посмотреть сообщение
Не, меня интересует в фоне относительно выполняемой инструкции. Т.е. чтобы инструкция не ждала, когда произойдёт выгрузка.
плохо понимаю, о чём идёт речь..

Цитата Сообщение от Jin X Посмотреть сообщение
Но канал памяти же один (ну или два изредка). Или читается сразу, скажем, целая страница (в какой-нибудь L3)? Как это всё работает?
без понятия.. нужно ворошить доки интела (или процессоров), может там найдутся ответы.
2
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
07.04.2020, 15:50
Цитата Сообщение от R71MT Посмотреть сообщение
плохо понимаю, о чём идёт речь..
Исполняется mov [eax],edx. В кэше строки из [eax] нет. Будет ли процессор ждать, когда произойдёт чтение-модификация-запись или перейдёт сразу к следующей инструкции (т.к. получать в ответ ничего не нужно).

Цитата Сообщение от R71MT Посмотреть сообщение
без понятия.. нужно ворошить доки интела (или процессоров), может там найдутся ответы.
Может ли читаться одновременно несколько строк из памяти?
1
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
07.04.2020, 17:30
Цитата Сообщение от R71MT Посмотреть сообщение
..так устроена запоминающая матрица динамической памяти
Подожди, ты рассказывашь про то, что происходит ВНУТРИ планки памяти DDR-2. В итоге ты все смешал в винегрет. Надо-же вычленять структурные объекты и рассматривать их как черные ящики, внутреннее устройство которых не важно. Какая разница что происходит ВНУТРИ DDR-2 ? DDR-2 - черный ящик, общение с которым идет через шину. Все. И по этой шине никаких 4 килобайт при необходимости записать один байт не считывается.
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
07.04.2020, 17:32
Цитата Сообщение от Jin X Посмотреть сообщение
Исполняется mov [eax],edx. В кэше строки из [eax] нет.
..такой ситуации не возникает, т.к. кэш заполняется нужными строками задолго до того, как EIP дойдёт до этой инструкции. Причём код попадает в кэш-инструкций I.L1, а данные в D.Ll. EIP вообще плетётся в хвосте, пока инструкции выполняются беспорядочно.

Когда программа только запускается, она имеет право 1-раз пробуксовать пару сек, в течении которых (по-мимо прочего) заполняются и кэш-линейки. В это время процессор может загребсти сразу всю открытую страницу из DRAM в свой кэш, а потом проанализировав, выставить флаг "Valid" только актуальным линейкам - остальные будут замещаться по-ходу пьессы. Когда-то я собирал инфу по кэшам здесь - можно глянуть на досуге.

Цитата Сообщение от Jin X Посмотреть сообщение
Может ли читаться одновременно несколько строк из памяти?
..только если память двуканальная.
В пакетном режиме, проц сначала засылает адрес-строки, и за ним.. выровненный на 64-байт границу адрес первого столбца кэш-строки. После того-как первые 8-байт лягут в SAMP, контроллёр включает пакетный счётчик-повторов BL=8, и дальше авто\увеличивается только адрес-столбца внутри открыто\удерживаемой страницы. То-есть за одну транзакацию на шине, адрес строки засылается только 1-раз, поэтому на одном канале невозможно прочитать одновременно несколько строк с разными адресами. Если-же контроллёр 2-канальный - то без проблем, т.к. у него своя шина адреса\данных. Как-то так..
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
07.04.2020, 17:38
Цитата Сообщение от Ethereal Посмотреть сообщение
И по этой шине никаких 4 килобайт при необходимости записать один байт не считывается.
нет конечно.. я говорил именно про DRAM

Не по теме:

заофтопили мы что-то всю тему

0
07.04.2020, 17:49

Не по теме:

Да нормально. Много чего интересного узнали.
Если бы все это развернуть в практическую плоскость - как заставлять процессор молотить данные быстрее, используя знания о его внутренней организации и организации памяти. Я пытался оптимизировать криптоалгоритмы используемых при майнинге, но результаты разочаровывали.
Хотя для щастья надо было всего-лишь чтобы указанный мною массив осел в самом быстром кеше и никуда оттуда не убирался. Может есть какие-то советы по этой области ?

0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6817 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,320
Записей в блоге: 12
07.04.2020, 19:15
Цитата Сообщение от R71MT Посмотреть сообщение
..такой ситуации не возникает, т.к. кэш заполняется нужными строками задолго до того, как EIP дойдёт до этой инструкции. Причём код попадает в кэш-инструкций I.L1, а данные в D.Ll. EIP вообще плетётся в хвосте, пока инструкции выполняются беспорядочно.
Ну как же они могут не возникать? Если бы такой ситуации не возникало, не было бы столько постов о том, как грамотно делать циклы, чтобы оптимизировать работу с кэшем.
Ну давай рассмотрим ситуацию, когда мы последовательно (или рендомно или ещё как-то) пишем 1 Гб памяти. Процессор при всём желании не сможет успеть заранее прочитывать всю память, инструкции всё равно будут выполняться быстрее.

Или даже ещё проще. Пример из Optimizing subroutines in assembly language (by A.Fog):
Assembler
1
2
3
4
5
6
7
again: mov eax, [edi]
mov ebx, [edi + 0804h]
mov ecx, [edi + 1000h]
mov edx, [edi + 5008h]
mov esi, [edi + 583ch]
sub ebp, 1
jnz again
В случае 4-полосного ассоциативного кэша размером 8Kb последний mov esi будет вытеснять сохранённую линию по адресу [edi] (т.к. все 5 mov'ов работают с одним и тем же, скажем, так, ключом, а полос всего 4). Далее, на втором круге, mov ebx вытеснит [edi + 0800h] и т.д. по кругу. Не будем брать во внимание тот факт, что далее идёт работа с L2, т.к. L2 всё равно меньше размером.

Ну не может быть такого, чтобы кэш был ВСЕГДА заполнен заранее. Иначе можно было бы не думать о кэше вообще. Посему и вопрос: будет ли тут ожидание чтения-модификации-записи или нет?
Если нет, значит это всё пишется либо в какой-то иной буфер, либо в L1 (если все ячейки НЕ-dirty, то сразу, а если все dirty, значит ждём записи и потом пишем, а как иначе?)
Если да, то почему movnt* работает быстро, а не сотню таков (ожидая, когда завершится запись).
0
E=m*c^2
 Аватар для K_ILYA_V
160 / 47 / 10
Регистрация: 04.02.2019
Сообщений: 263
Записей в блоге: 5
07.04.2020, 20:00  [ТС]
Цитата Сообщение от R71MT Посмотреть сообщение

Не по теме:

заофтопили мы что-то всю тему

можете ли высказаться по такому вопросу.

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

это не рабочий код исключительно для иллюстрации вопроса:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    proc1 proc
    lea rsp,d0
    jmp m0
    d0:
        dq m3
        dq m2
        dq m1
        dq m5
 
    m3: xor rsi,rsi
    m2: xor rdx,rdx
    m1: xor rcx,rcx
    m0: xor rbx,rbx
        xor rax,rax
        ret
    m5:
 
proc1 endp
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6215 / 2449 / 403
Регистрация: 29.07.2014
Сообщений: 3,181
Записей в блоге: 4
07.04.2020, 20:16
Цитата Сообщение от Jin X Посмотреть сообщение
Или даже ещё проще. Пример из Optimizing subroutines in assembly language (by A.Fog)
это заведомо кривой код, и Intel прямым текстом говорит,
что в этом случае кэш будет проседать.

Цитата Сообщение от Jin X Посмотреть сообщение
Если да, то почему movnt* работает быстро, а не сотню таков (ожидая, когда завершится запись)
может потому, что это не время записи в память, а время декодирования инструкции?
работа тандема кэшей всех ядер вообще покрыта тайной, и внятных доков по ней трудной найти.

Добавлено через 6 минут
Цитата Сообщение от K_ILYA_V Посмотреть сообщение
вызовет ли это замедление при работе?
Стек - это такая-же секция данных, и он тоже кэшируется, так-то наврядли вызовет тормоза.
Кстати Крис рекомендовал сей финт ещё давно, как быстрый доступ к стеку.
0
E=m*c^2
 Аватар для K_ILYA_V
160 / 47 / 10
Регистрация: 04.02.2019
Сообщений: 263
Записей в блоге: 5
07.04.2020, 20:27  [ТС]
я беспокоюсь не будет ли обращение к стеку за данными "срывать" загрузку инструкций. ведь я так думаю кешь кода может выдавать только одну порцию данных за такт. то есть после декодирования ret когда проц установит необходимость в загрузке данных он прервет процесс загрузки кода до момента получения данных.

Добавлено через 1 минуту
различаются ли физически кеши данных и кода? может кешь кода физически расположенны ближе к "входу" в проц чтобы обеспечить выдачу команд "такт в такт"
0
E=m*c^2
 Аватар для K_ILYA_V
160 / 47 / 10
Регистрация: 04.02.2019
Сообщений: 263
Записей в блоге: 5
07.04.2020, 20:30  [ТС]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.04.2020, 20:30

push и pop
У меня возникла странная проблема. Мы создали сайт на основе системы управления, которой пользовались не один раз. Все сайты нормально...

Функции pop и push
Здравствуйте, есть код, решающий задачу. В нем есть стандартные функции push и pop. Как можно расписать функции подробно pop и push?...

Работа с push/pop в стеке
Здравствуйте, я тут столкнулся с проблемой, не могу понять, как работать со стеком. Ниже приведу код, чтобы показать ситуацию, просто для...

Верна ли реализация push/pop?
Правильный ли у меня ход мыслей при написании кода, на тему реализации стека? #include <stdio.h> #include <stdlib.h> ...

PUSH/POP vs MOV из памяти
Какой из двух ниже перечисленных примеров занимает меньше процессорного времени (тактов) ? 1: @@: PUSH ESI ;тут некий код POP...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru