Форум программистов, компьютерный форум, киберфорум
Наши страницы
Низкоуровневое программирование
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
1

Память компьютера

21.10.2017, 01:59. Просмотров 3213. Ответов 12
Метки нет (Все метки)

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

Подсистема памяти - наиболее мутная и сложная часть архитектуры,
и на мой взгляд программирование нужно начинать именно с неё.
По настроению и времени - буду дополняться.
(хотя что-бы охватить весь материал, наверное не хватит и всей жизни).
-------------------------------------------


ПРОЦЕССОР. БЛОК УПРАВЛЕНИЯ ПАМЯТЬЮ

Процессоры изначально заточены под сегментную организацию памяти, иначе зачем было вводить шесть сегментных регистров CS..FS. Более того, они не имеют механизмов запрещения сегментации, тогда-как страничную трансляцию можно включать\выключать битом(31-PAGE) регистра управления процессором(CR0).
В аппаратной части подсистемы памяти фигурируют 3 типа адресов: логический, линейный и физический. Из этой троицы, ЦП оперирует только логическим адресом, который использует в своих программах программист. Для трансляции остальных адресов, процессор имеет блок управления памятью - MMU (Memory Management Unit).

Логический адрес состоит из сегмента и смещения - CS:EIP, DS:ESI, ES:EDI, etc. MMU собирает эти составляющие, преобразуя лог\адрес в линейный (в диапазоне 0..N). Если в регистре(CR0) включён страничный режим, то в дело вступает транслятор страниц MMU. Если-же страничное преобразование выключено, то линейный адрес совпадает с физическим, который и выставляется процессором на внешнюю шину-адреса. Схематически это выглядит так (в сегментных регистрах лежит 2-байтный селектор сегмента, EA - смещение, тёмным выделены блоки MMU):



На этом рисунке бит 'PAGE' в регистре(CR0) имеет значение нуль, т.е. страничная трансляция отключена и вся физическая память разбита только на сегменты. Линейный адрес совпадает с физическим. Если установить 'PAGE=1', то перемычка с транслятора страниц снимается, и на сегментную организацию накладывается страничная - блоки фиксированного размера по 4Кб, которые составляют виртуальную память. Только при использовании страничной трансляции доступны 36-битные физические адреса до 64-Гбайт (PSE, PAE).

В сегментной модели, память представляется группой независимых блоков. Для адресации байта, программа использует логический адрес состоящий из селектора сегмента, и смещения. Селектор выбирает определённый сегмент, а смещение указывает на конкретный байт в пространстве выбранного сегмента:



Селекторы хранятся в сегментных регистрах. При трансляции логического адреса в линейный, смещение выставляется на шину без модификации. Вся трансляция сводится к тому, чтобы найти в памяти базу указанного сегмента, и прибавить к ней смещение. Адрес базы хранится в дескрипторе сегмента.


ДЕСКРИПТОР - БАЗА, ЛИМИТ, ЗАЩИТА

В защищённом режиме размер сегментов может быть произвольным: от 1-байта до 4-Гбайт. Любому из них в отдельности можно задавать свои атрибуты(Access) и ограничивать доступ двойной защитой. От сюда и название режима - защищённый - Protected! Во-первых можно указать уровень привелегий (RPL), т.е. с какого из 4-х колец защиты(0-3) возможен доступ к сегменту. Во-вторых - какие можно проводить операции с его данными: чтение, запись, исполнение.



Каждый сегмент памяти описывает его-собственный дескриптор. Размер дескриптора 8-байт (64-бита). В нём хранится линейный адрес начала сегмента в памяти (Base=32-бит), размер сегмента (Limit=20-бит), и атрибуты защиты (Access=12-бит). При обращении к сегменту, MMU сначала проверяет значение смещения, которое не должно превышать лимит. То есть адрес не должен выходить за пределы сегмента, в противном случае ЦП сгенерит исключение.

Если с базой и атрибутами ситуация прозрачна, то к лимиту есть вопросы..
Например, как 20-ю битами определить размер сегмента в 4-Гб? Ответ - его размер указывается в единицах измерения! Среди атрибутов, в дескрипторе имеется т.н. бит гранулярности(G). Если он сброшен, то единицей измерения считается байт, если взведён - то 4-Кбайтная страница. Отсюда следует, что при G=0 размер\лимит сегмента ограничен значением 1.048.576 байт (20-бит = 1Мб), а при G=1 включается множитель(4Кб): 1048576*4096=4 Гбайт.



ТАБЛИЦЫ ДЕСКРИПТОРОВ - GDT, LDT, IDT

Обычно программа занимает несколько сегментов памяти: кода(CS), данных(DS), стека(SS). У каждого из них свой дескриптор. Итого - три., плюс три вспомогательных сегмента, на которые указывают ES\FS\GS. Внутри одной задачи (программы), все её дескрипторы собираются в Таблицу дескрипторов. Таких таблиц тоже всего три:

-1. Глобальная таблица дескрипторов(GDT) - системная и может быть только одна. Доступна всем задачам, если не нарушаются права доступа. Обычно GDT включает дескрипторы сегментов кода и данных ОС, сегментов состояния задач(TSS). Под дескрипторную таблицу текущей задачи(LDT) выделяется отдельный сегмент. Дескриптор этого сегмента хранится в GDT.

-2. Локальная таблица(LDT) для каждой задачи своя. Их кол-во определяется кол-вом активных задач в системе: LDT-1,2,3,,N. К локальным дескрипторам может обращаться только та задача, в таблице которой эти дескрипторы прописаны. В каждый момент времени процессору доступна только одна из локальных таблиц(LDT) - таблица текущей задачи.

-3. Таблица прерываний(IDT) служит заменой таблицы векторов прерываний реального режима. Процессор обращается к ней при возникновении аппаратных исключений. Прямой доступ со стороны прикладной задачи к сегменту IDT не возможен, т.к. бит индикатора таблицы(TI) в селекторе сегмента позволяет выбирать только GDT или LDT. В этой таблице хранятся дескрипторы шлюзов-прерываний и ловушек, по аналогии с векторами реального режима.

Все эти таблицы хранятся в памяти, а их физические адреса лежат в регистрах процессора GDTR, LDTR, IDTR соответственно. Команды записи [LGDT\LLDT\LIDT] в них являются привелигерованными (запись возможна только с нулевого кольца), зато чтение в PMode никак не препядствуется процессором: SGDT\SLDT\SIDT.

Кроме этих таблиц, в окружении задачи обязательно присутствует сегмент TSS (Task State Segment) - сегмент состояния задачи. При переключении задач, в этот сегмент сбрасывается полная инфа о текущей задаче - ccылка на предыдущую запись TSS (для восстановления приостановленной задачи), текущее состояние всех (кроме FPU) регистров ЦП, указатели на внутренний стек, битовая карта прерываний, и пр. Описание сегмента(TSS) можно найти здесь: http://www.club155.ru/x86addr-tss, или в манах Intel'a Vol.3. Селектор дескриптора(TSS) хранится в регистре(TR) процессора - Task Register.

Нужно отметить, что кроме дескрипторов 'своих' сегментов, в локальной таблице(LDR) присутствуют и сегменты ОС. То есть в пространстве памяти есть общие для всех сегменты. Это касается импортируемых API-функций системы. Эти функции лежат в сегментах памяти ОСи, к которым нет прямого доступа из прикладного уровня. Поэтому ОС (в зависимости от импорта) дополняет LDT текущей задачи, некоторыми дескрипторами из своей\глобальной таблицы. Такой подход исключает переключение задач при вызове API. Прикладной задаче разрешено читать только те сегменты ОСи, которые она прописала в её локальную таблицу дескрипторов(LDT).
7
Миниатюры
Память компьютера   Память компьютера   Память компьютера  

Память компьютера  
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.10.2017, 01:59
Ответы с готовыми решениями:

Обсуждение статьи "Память компьютера"
Обсуждение статьи http://www.cyberforum.ru/low-level/thread2107770.html Вот про флаговые биты...

Почему в TASM нельзя сравнивать память-память?
То есть я понимаю, что можно либо регистр-память, либо память-регистр, либо регистр-регистр. Но...

Память компьютера
Добрый вечер. Можете ли по подробнее рассказать о памяти компьютера? Как компьютер хранит...

Уменьшилась память компьютера
Вообщем проблема такая, я что то натворил и теперь у меня жесткий диск за место 500гБайт стал всего...

Процессы и память компьютера
Вопрос простой: сумма памяти используемая всеми процессами меньше четь ли не в два раза чем указано...

12
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
21.10.2017, 02:06  [ТС] 2
СЕГМЕНТНЫЕ РЕГИСТРЫ. СЕЛЕКТОР

В защищённом режиме, основной функцией сегментных регистров является определение местоположения дескрипторов. Начиная с процесоров i286 размер регистров CS..FS не 2, а 10-байт. Из них программно доступны только старшие 2-байта, в которых хранится т.н. Селектор дескриптора. Селектор - это номер дескриптора в таблице (GDT\LDT). Получается цепочка - селектор указывает на дескриптор, а дескриптор описывает физический сегмент памяти.

Младшие 8-байт сегментного регистра программно недоступны - затенены. В них на аппаратном уровне копируется весь 8-байтный дескриптор, на который указывает данный селектор. Один раз скопировав дескриптор в сегментный регистр, MMU (в течении одной задачи) больше не обращается к таблице дескрипторов вообще.

В манах интела можно найти состояние упомянутых регистров при включении машины. Хоть это и реальный режим, зато отчётливо видны в сегментных регистрах: 2-байтный\видимый селектор, и скрытая\8-байтная часть - база, размер и атрибуты, т.е. те-же поля, что и в дескрипторах.

Заслуживают внимания и стартовые значения регистровой пары CS:EIP, которая при таких значениях передаёт управление по логическому адресу F000:FFF0h (линейный адрес FFFF0h), где находится первая инструкция кода BIOS:



Селектор - это часть логического адреса. Посмотрим на описание его полей:

Код
       15-----------------3  2   1-0
        __________________ ____ _____ 
       |      Индекс      | TI | RPL |
       |__________________|____|_____|

  Биты(0-1)  =  2-бита для уровня RPL - Requested Privilege Level (4 кольца защиты);
  Бит(2)     =  1-бит выбора таблицы - GDT или LDT;
  Биты(3-15) =  13-бит для номера дескриптора в таблице.
Здесь видно, что номер дескриптора кодируется 13-ю битами. Значит в одной дескрипторной таблице может быть всего 8192-дескриптора. Таблиц всего две - GDT и LDT: 8192*2=16384 дескриптора. Поскольку каждый из них описывает один сегмент, выходит что именно столько сегментов может иметь прикладная задача. Если размер одного дескриптора равен 8-байт, то под-макушку забитые таблицы займут в памяти 8192*8=64Кб. Максимальный лимит одного сегмента равен 4-Гига, - умножаем его на 16384, и получаем доступное пространство одной задачи при сегментной организиции памяти - 64 Терабайт.

Когда MMU транслирует логический адрес он, проверив в селекторе биты(TI-RPL), обнуляет их. Сброс трёх-младших битов селектора приводит к тому, что индекс всегда получается кратным восьми, - а это как раз размер одного дескриптора. В результате - индекс превращается в адрес в таблице(LDT). Нулевой дескриптор в таблицах не используется и должен быть забит нулями:

Код
         |    Kernel (RPL=0)   ||     User (RPL=3)    | 
Регистры |    селектор (bin)   ||    селектор (bin)   | Регистры
---------|---------------------||---------------------|---------
 CS=08h  - 0000000000001.0.00  ||  0000000000011.0.11 -  CS=1Bh 
 DS=10h  - 0000000000010.0.00  ||  0000000000100.0.11 -  DS=23h
 SS=18h  - 0000000000011.0.00  ||  0000000000101.0.11 -  SS=2Bh
 ES=20h  - 0000000000100.0.00  ||  0000000000110.0.11 -  ES=33h
 FS=28h  - 0000000000101.0.00  ||  0000000000111.0.11 -  FS=3Bh
 GS=30h  - 0000000000110.0.00  ||  0000000001000.0.11 -  GS=43h
В системах класса(NT), виндозный менеджер памяти всегда выставляет одни и те-же значения в селекторы сегментных регистров. Если это кодовый(CS) селектор ядра, то его дескриптор будет лежать по смещению(08h) от начала дескрипторной таблицы, в то время как для прикладной задачи этот селектор будет указывать на адрес(1Bh). Менеджер специально сдвигает базу юзерской таблицы на 1Bh-08h=13h вверх, чтобы при любых обстоятельствах селекторы дескрипторов Kernel и User не пресекались. Селекторы ядра всегда имеют чётные номера, а прикладной задачи - нечётные.

Селекторы остальных сегментных регистров будут увеличиваться в таблице на 8 (размер одного дескриптора). В этом легко убедиться, если открыть любую программу в отладчике OllyDbg, и посмотреть на их значения (в сл.полях лежат база с лимитом - скрытая часть регистра):

Код
ES   0023  32bit  0(FFFFFFFF)
CS   001B  32bit  0(FFFFFFFF)
SS   0023  32bit  0(FFFFFFFF)
DS   0023  32bit  0(FFFFFFFF)
FS   003B  32bit  7FFDF000(FFF)
GS   0000  NULL

EDX  7C90E4F4 ntdll.KiFastSystemCallRet
EBX  7FFD9000
ESP  0006FFC4
EBP  0006FFF0
EDI  7C910208 ntdll.7C910208
EIP  00403000 002.
Для опытов с селекторами ядра Оля уже не годится, и нужно искать ядерный отладчик (отладчик уровня ядра), например китайский Syser или WinDBG от мелкософта.
7
Миниатюры
Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
28.10.2017, 11:09  [ТС] 3
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

SYSER KERNEL DEBUGGER

Все, кто имел дело с легендарным отладчиком SoftIce знают насколько мощный это инструмент. Только вот проблема - он не дружит с платформами WinХР+. Вернее нужно добавлять левые патчи и не факт, что после этого мы увидим долгожданное окно отладчика. Автор перепробовал много советов из сети, но так и не добился результата. Этих недостатков лишён "SYSER" - китайский клон Айса, о котором хотелось-бы сказать пару слов.

Установка проходит в штатном режиме без эксцессов. Отладчик имеет резидентные (невыгружаемые) модули, поэтому нужна перезагрузка, после которой можно в любой момент вызвать его комбинацией [Ctrl+F12] и исследовать ядро прямо из под винды. Мастдай при этом получает глухой завис, пока не выйдешь из отладки. Консоль имеет мощную справку, причём для каждой команды в отдельности и с примерами. Ведение логов со-сбросом их в файл. Юсбишная мыша в окне не работает, - только PS\2.
----------------------------

В реальном режиме, под систему выделяются младшие адреса памяти. В винде наоборот - старшая половина. Если проц 32-битный, то и шина-адреса у него 32-бит с макс.адресом 0xFFFFFFFF (4Гб). Система выделяет для юзера область в диапазоне 00010000-7FFFFFFFh, а сама занимает адреса 80000000h и выше. Юзерскую кучу с двух сторон подпирают два спец\буфера по 64Кб для вылавливания некорректных указателей. Обращения к этим областям из юзер-моды расценивается виндой как нарушение периметра неприятелем и жёстко пресекаются. Поэтому пользовательское пространство начинается с адреса 0х00010000, а не ноль. (напомню, что это виртуальные VA-адреса, и физ\памяти может столько не быть):
Код
          |<------ User memory ------->|     |<----- Kernel memory ---->|
          |                            |     |                          |
    |FFFFh|----------------------------|FFFFh|--------------------------|
    |-----+-----> 64к   +   64к <------+-----+                          |
    |                                  |                                |
    |<--0x00000000h               0x80000000               0xFFFFFFFF-->|
На любую теорию должна накладываться практика, иначе у каждого включается своё воображение. Например выше, речь шла о таблицах GDT\LDT\IDT и сегменте(TSS). Но какая у них структура и где они находятся в памяти - сам чёрт не разберёт. Вот здесь-то и приходит на помощь "Syser", который раскроет перед нами все карты (памяти). Посмотрим на структуры этих таблиц, для чего нужно открыть любую Win32-программу в отладчике и дать ему соответствующее направление.

После запуска 'клон-Айса', в его консоли сразу появляется инфа о кол-ве процедур экспортируемых каждой из системных библиотек, кол-ве найденых в системе API (2791), и названия файла ядра - 'ntoskrnl.exe' - кернел оси NT. Одной из основных назначений ядерных отладчиков является перехват системных ошибок (всплытие по ошибке), чтобы админ смог локализовать и исправить её. Самый коварный из ошибок - это BSOD, захлопывающий перед админом все двери. Его обрабатывает API "KeBugCheckEx", адрес которой и показывает Syser.

Если быть точным, то лог показывает не кол-во экспортируемых функций (например для 'Kernel32.dll' указано 937), а кол-во символьных таблиц (Symbols), что по сути одно и то-же. Таблицы символов содержат имена API-функций и переменных в конкретном файле. Они генерируются линкером, но не включаются в экзешник, поскольку для выполнении кода эта инфа не нужна - линкер превращает имена в их адреса. Как видим Syser хорошо вооружён, и способен распознать приличное кол-во имён API-функций. Таблицу символов Syser хранит в файле 'mfcsym.txt' размером ~1Mb:
Код
Syser : Version 1.99.1900.1217   Build 04/27/2011

Syser : Load module   937 export symbols  C:\WINDOWS\system32\Kernel32.dll
Syser : Load module   596 export symbols  C:\WINDOWS\system32\GDI32.dll
Syser : Load module   720 export symbols  C:\WINDOWS\system32\User32.dll
Syser : Load module   648 export symbols  C:\WINDOWS\system32\AdvApi32.dll
Syser : Load module   114 export symbols  C:\WINDOWS\system32\ws2_32.dll
Syser : Load module   815 export symbols  C:\WINDOWS\system32\msvcrt.dll
Syser : Load module    28 export symbols  C:\WINDOWS\system32\comdlg32.dll
Syser : Load module   169 export symbols  C:\WINDOWS\system32\comctl32.dll
Syser : Load module   109 export symbols  C:\WINDOWS\system32\ImageHlp.dll
Syser : Load module   221 export symbols  C:\WINDOWS\system32\win32k.sys
Syser : Load module  1016 export symbols  C:\WINDOWS\system32\ntdll.dll
Syser : Load module    92 export symbols  C:\WINDOWS\system32\hal.dll
Syser : Load module  1461 export symbols  C:\WINDOWS\system32\ntoskrnl.exe

Syser : Load API     2791 records

Syser : Windows kernel name 'ntoskrnl.exe' Base = 804d7000
Syser : Patch KeBugCheckEx = 805337EB
Syser : You can press "CTRL+F12" to active Syser !
>
Добавлено через 3 минуты
Регистры процессора

Теперь, из окна отладчика перейдём на консоль(Ctrl+2), и посмотрим на регистры..
Поскольку речь идёт о памяти, нам интересны только адреса. А это значения селекторов в сегментных регистрах, флаги в CR(0..4), и базы расположения дескрипторных таблиц(GDT..LDT). Регистры(РОН) я исключил из этого списка.

Здесь видно, что в отладчик загружена программа прикладного уровня (CS=1Bh, а не 08h), данные и стек делят один сегмент, зато селектор(FS=3Bh). Его дескриптор указывает на первый SEH-фрейм, где хранится цепочка обработчиков исключений Win. Эта область находится за макушкой текущего стека. SEH (Structured Exception Handling) - это отдельная тема, и позже мы ознакомимся с общими принципами работы этого механизма.

Отладочные (Debug) регистры - это вообще жесть! Доступ к ним возможен только с Ring(0), или в реальном режиме. Непросвящённым, советую ознакомиться с этими регистрами по ближе. Они служат для описания характера точек останова (BreakPoint). Битовые маски позволяют ставить BP отдельно на: операции с памятью (R\W\Exec), программные\аппартные прерывания, и обращения к портам ввода-вывода. При помощи бряков на I\O можно написать полноценный эмулятор на любое из внешних устройств.

В регистрах управления процессором (Control) зашита инфа об организации памяти и кэша. По сути, эти биты вкл\откл отдельные блоки ЦП, в том числе и трансляторы адресов в MMU. Бит(РЕ) в регистре(CR0) от слова 'PageEnable' - включает транслятор страниц (виртуальную память). В регистре(CR3) хранится линейный адрес начала таблицы PDT - PageDirectoryTable - таблица каталога страниц виртуальной памяти. В битах регистра(CR4): PSE = 4-Мбайтные страницы (иначе 4-Кбайт), PAE = 36-битный адрес (иначе 32), и т.д..

Ну и последними в списке регистров находятся данные о расположение в памяти дескрипторных таблиц (регистры GDTR..LDTR). Из отчёта видно, что их базы находятся в системной области памяти (выше 0х80000000), причём лимиты (размеры) у каждой из таблиц разные. Если у вас многоядерный ЦП, то в команде консоли нужно указать номер ядра:
Код
>> cpu 0
Segment Register
CS=0x001B, DS=0x0023, ES=0x0023, FS=0x003B, GS=0x0000, SS=0x0023

Debug Register
DR0=0x00000000, DR1=0x00000000, DR2=0x00000000, DR3=0x00000000
DR6=0xFFFF0FF0, DR7=0x00000400

Control Register
CR0=0x80010031, CR2=0x7C86495C, CR3=0x17CEF000, CR4=0x000006D9
CR0:  PE=1  MP=0  EM=0  TS=0  ET=1  NE=1  WP=1  AM=0  CD=0  PG=1
CR3:  PWT=0  PCD=0  Page-Directory Base = 17CEF000
CR4:  VEM=1  PVI=0  TSD=0  DE=1  PSE=1  PAE=0  MCE=1  PGE=1  PCE=0  OSFXSR=1  OSXMMEXCPT=1

GDT                 Base=8003F000  Limit=03FF
IDT                 Base=8003F400  Limit=07FF
TSS  Selector=0028  Base=80042000  Limit=20AB  
LDT  Selector=0000  Base=00000000  Limit=FF394D44
Добавлено через 5 минут
Дескрипторные таблицы GDT\LDT

Содержимое дескрипторных таблиц таит в себе много тайн и загадок, которые 'Syser' решает в два-счёта. Введём с консоли их имена и посмотрим на реакцию отладчика. Упс - нет таблицы(LDT). Значит все сегменты моей программы описывают дескрипторы глобальной таблицы(GDT), и LDT для прикладной задачи не так важна. Зато GDT забита дескрипторами под-завязку. Я не стал выкладывать сюда всю портянку, а ограничился лишь наиболее информативными из них. В логе указываются номера селекторов в сегментных регистрах, тип дескриптора в таблице, и его содержимое - линейный адрес базы сегмента в памяти, его размер и атрибуты.

DPL (Descriptor Privelege Level) - определяет, кто хозяин дескриптора (Ring): 0=ядро, 1=драйвер, 2=сис\библиотеки, 3=юзер. NP (NoPresent) = сегмент не активен. Атрибут(E) = 'Exec' исполнение (выставляется только в сегментах кода), (А) = 'Accessed' устанавливается при любом обращении к сегменту, чтобы выявлять сегменты, к которым меньше всего было обращений (например, раз в 10-сек). При ограниченном кол-ве физ\памяти, система сбрасывает сегменты без бита(А) в своп на диск.

Вообще-то, среди атрибутов дескриптора сегмента должен быть ещё и бит(E) - 'Expand Down', который определяет направление роста адресов в сегменте, но почему-то 'Syser' его не отображает. Этот бит применяется только к сегментам данных. Поскольку между сегментами данных и стека нет особой разницы кроме-как направление роста адреса (неисполняемый стек), то выставленный бит(E) в сегменте данных определял сегмент стека, где сл.адрес уменьшается, а не увеличивается.

Напомню про базовые адреса сегментов.. Если старший байт базы равен(0x7F) и ниже, то сегмент юзерский, если (0x80) и выше - то им заправляет система. Сам сегмент(GDT) занимает в памяти 1-Кбайт (3FFh), и лежит в младших адресах системы 0x8003F000. Если размер одного дескриптора 8-байт, то выходит, что в данной таблице имеется место под 1024/8=128 дескриптора, хотя сам сегмент(GDT) может расширятся динамически и 128-дескрипторов в нём - это не предел.<P>

По содержимому GDT можно определить, сколько прикладных задач запущено в системе. Поскольку каждая из задач имеет свой TSS - Task State Segment, то достаточно посчитать кол-во их дескрипторов - здесь 4 штуки с селекторами 28,50,58,A0. И точно.. на тот момент у меня были запущены: Тотал, Опера, AkelPad и сам отладчик 'Syser'. На отладчик я переключился из AkelPad'a, а система сразу сбросила контекст Akela'a в его сегмент(TSS), и выставила в текущем TSS отладчика атрибут(В), т.е. 'Busy' - занятый. Процессор не поддерживает рекурсию задач (вызов самой-себя), для чего и используется этот бит(Busy):
Код
>> ldt
No LDT
----------
>> gdt
GDTBase = 8003F000   Limit = 3FF
----------------------------------------------------
Sel.  Type      Base      Limit     DPL  Attributes
0000  Reserved  00000000  00000000  0    NP         
0008  Code32    00000000  FFFFFFFF  0    P   RE    A
0010  Data32    00000000  FFFFFFFF  0    P   RW    A
001B  Code32    00000000  FFFFFFFF  3    P   RE    A
0023  Data32    00000000  FFFFFFFF  3    P   RW    A
0028  TSS32     80042000  000020AB  0    P   B      
0030  Data32    FFDFF000  00001FFF  0    P   RW    A
003B  Data32    7FFDF000  00000FFF  3    P   RW    A
0043  Data16    00000400  0000FFFF  3    P   RW     
0048  Reserved  00000000  00000000  0    NP         
0050  TSS32     80551380  00000068  0    P          
0058  TSS32     805513E8  00000068  0    P          
0060  Data16    00022F40  0000FFFF  0    P   RW    A
0068  Data16    000B8000  00003FFF  0    P   RW     
0070  Data16    FFFF7000  000003FF  0    P   RW     
0078  Code16    80400000  0000FFFF  0    P   RE     
0080  Data16    80400000  0000FFFF  0    P   RW     
0088  Data16    00000000  00000000  0    P   RW     
0090  Reserved  00000000  00000000  0    NP         
0098  Reserved  00000000  00000000  0    NP         
00A0  TSS32     82BC4358  00000068  0    P          
00A8  Reserved  00000000  00000000  0    NP         
...........
00D8  Reserved  00000000  00000000  0    NP         
00E0  Code16    F7708000  0000FFFF  0    P   RE C  A
00E8  Data16    00000000  0000FFFF  0    P   RW     
00F0  Code16    804D8B28  00037CA7  0    P   EO     
00F8  Data16    00000000  0000FFFF  0    P   RW     
0100  Data32    F7718000  0000FFFF  0    P   RW    A
0108  Data32    F7718000  0000FFFF  0    P   RW    A
0110  Data32    F7718000  0000FFFF  0    P   RW    A
0118  Reserved  00008003  0000F120  0    NP         
...........
03F8  Reserved  00000000  00000000  0    NP
7
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
28.10.2017, 11:11  [ТС] 4
IDT - Interrupt Dispatch Table (диспетчеризация прерываний)

Как и GDT - эта таблица общая для всех задач, и система выделяет для них отдельные сегменты. Обращение к IDT возможно только на аппаратном уровне при возникновении исключений или аппаратных инт'ов. В таблице расписаны номера всех прерываний, которые в P-Mode называют дескрипторами шлюзов. Имеется всего три типа этих шлюзов: шлюз-прерывания 'Int' (точка входа в обработчик прерывания), шлюз-ловушки 'Trap' (адрес обработчиков исключений, как-правило SEH), и шлюз-задачи 'Task' (адреса TSS для переключения задач).

Для наглядности, я рассортировал их здесь по содержимому и уровням привелегий(DPL). В таблице всего 256 записей с макс.номером(FFh). Для каждого INT выделены свои дескрипторы. Между шлюзами прерываний и ловушек много общего, поэтому 'Syser' их не разделяет, хотя шлюз-задачи удостоился от отладчика личной метки (Task).

При генерации прерывания происходит следующее..

1. Из регистра(IDTR) извлекается база таблицы(IDT), в которой по номеру INT определяется дескриптор этого прерывания.

2. Если бит(Р) - 'Present' - в найденном дескрипторе сброшен, значит данное прерывание не обрабатывается системой. В этом случае генерится исключение общей защиты.

3. Если бит(Р=1), то проверяется уровень привилегий (RPL) задачи, запросившей прерывание. RPL должен быть меньше\равно DPL дескриптора прерывания, иначе - опять ошибка. (для исключений и аппаратных прерываний этот пункт игнорируется).

4. Если правила не нарушаются, то происходит переключение стека и в стеке обработчика сохраняется указатель на стек прерванной задачи (SS:ESP). В стек помещаются регистры EFLAGS и CS:EIP. Для некоторых исключений последним в стек помещается ещё и код-ошибки.

5. После обработки прерывания, обработчик должен вытолкнуть из стека код-ошибки (если он там есть), и выполнить инструкцию IRETD, которая восстановит стек и вернёт управление прикладной задаче:
Код
>> idt
IDTBase = 8003F400   Limit = 7FF
-----------------------------------------------------------------
Int   Type      Sel : Offset                 Attributes    Module
0000  IntG32    0008:804DF360                DPL=0 P       ntoskrnl
000E  IntG32    0008:F200A5C0(0008:804E167E) DPL=0 P       Syser(ntoskrnl)
0013  IntG32    0008:804E1CAC(0008:804E18F3) DPL=0 P       ntoskrnl(ntoskrnl)
001F  IntG32    0008:80712FD0(0008:804E18F3) DPL=0 P       hal(ntoskrnl)
00FF  IntG32    0008:804DE4D0                DPL=0 P       ntoskrnl

0002  TaskG     0058:0000113E(0008:804DF5C6) DPL=0 P       (ntoskrnl)
0008  TaskG     0050:00001198(0008:804E06AD) DPL=0 P       (ntoskrnl)
0012  TaskG     00A0:804E18F3                DPL=0 P       ntoskrnl

0001  IntG32    0008:804DF4DB                DPL=3 P       ntoskrnl
0003  IntG32    0008:804DF8AD                DPL=3 P       ntoskrnl
0004  IntG32    0008:804DFA30                DPL=3 P       ntoskrnl
002A  IntG32    0008:804DEBA2                DPL=3 P       ntoskrnl
002B  IntG32    0008:804DECA5                DPL=3 P       ntoskrnl
002C  IntG32    0008:804DEE44                DPL=3 P       ntoskrnl
002D  IntG32    0008:F7ABCF96(0008:804DF78C) DPL=3 P       SDbgMsg(ntoskrnl)
002E  IntG32    0008:804DE631                DPL=3 P       ntoskrnl
002C  IntG32    0008:804DEE44                DPL=3 P       ntoskrnl
002D  IntG32    0008:F7ABCF96(0008:804DF78C) DPL=3 P       SDbgMsg(ntoskrnl)

0020  Reserved  0008:00000000                DPL=0 NP      
..........
0029  Reserved  0008:00000000                DPL=0 NP      

00FC  IntG32    0008:804DE4BB                DPL=0 P       ntoskrnl
00FD  IntG32    0008:80713464(0008:804DE4C2) DPL=0 P       hal(ntoskrnl)
00FE  IntG32    0008:80713604(0008:804DE4C9) DPL=0 P       hal(ntoskrnl)
00FF  IntG32    0008:804DE4D0                DPL=0 P       ntoskrnl
7
28.10.2017, 11:11
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
28.10.2017, 11:18  [ТС] 5
Сегмент состояния задачи TSS

В заключении посмотрим, какой контекст сбрасывается в сегмент(TSS) при переключении задач, для её возобновления с того-же места.

Указывающий на дескриптор(TSS) селектор, хранится в регистре(TR) процессора - 'Task Register'. Дескрипторы(TSS) каждой из запущенных задач должны быть прописаны в GDT (см.структуру GDT выше), причём в одном из них выставляется бит(В) - 'Busy' - занятый. Это дескриптор(TSS) активной задачи.

Сегмент(TSS) содержит динамические и статические поля. К динамическим относятся поля для хранения РОН и адрес дескриптора(TSS) той задачи, с которой было переключение - 'Previous Task Link'. ЦП обновляет динамические поля при сохранении контекста задачи, во время переключения на другую задачу.

К статическим полям относятся все\остальные: селектор(LDT), регистр(CR3) содержайщий адрес каталога страниц, указатели системных стеков SS:ESP(0,1,2), и базовый адрес карты разрешения ввода-вывода (I\O Permission Map Base Address). Статические поля заполняются системой при запуске задачи (создании TSS) и не меняются при переключении задач.

Для управления вводом-выводом и прерываниями, в TSS имеются два бит-мапа.
'I\O Permission Map' используется при работе юзера с портами, т.е. когда IOPL меньше CPL (инструкции in\out). Если в этой карте бит соответствующий запрашиваемому порту равен(0), операция ввода-вывода проходит успешно, в противном случае генерится нарушение общей защиты. Таким образом получается двойная защита - привелегия(IOPL) и битовая карта разрешения в\в. Отсутсвие этой карты расценивается как запрет на ввод-вывод из Ring(3). Она введена только для прикладных задач.

Вторая карта - это карта перенаправления прерываний - 'INT redirection bit-map'.
Она имеет размер 32-байта, что позволяет перенаправлять: 32 * 8 (бит) = 256 пользовательских прерываний. Каждый бит в этом битмапе соответствует одному прерыванию, который отображается на соответствующий дескриптор в таблице(IDT). Если бит прерывания(INT) в битмапе взведён, то управление передаётся через дескриптор(IDT) обработчику защищённого режима. Когда бит сброшен, ЦП переназначает программное прерывание на таблицу векторов прерываний х8086, которая расположена по линейному адресу(0) юзерского пространства. Этот битмап используется в режиме V86 процессора:
Код
>> tss
TR = 0028   BASE = 80042000   LIMIT = 20AB

LDT=0000  GS=0855  FS=5501  DS=0F56  SS=8B24  CS=8510  ES=EC8B
EAX=1875FFEC  EBX=FFFF02E8  ECX=FF1475FF  EDX=55FF8B00  EIP=001CC2C9
ESI=14C25DFF  EDI=55FF8B00  EBP=FFFF02E8  ESP=0875FF00  EFL=8B55FF8B

CR3 = 17CEF000
SS0 = 0010:F5D58DE0  SS1 = 4338:D0685000  SS2 = C483:FFFF33B5

I/O permission map.....:  BASE = 20AC,     SIZE = 0
INT redirection bit-map:  BASE = 80042068, SIZE = 32

                   0 1 2 3 4 5 6 7 - 8 9 A B C D E F
                   ------------------------------------
0x80042068  0400   0 0 1 0 0 0 0 0 - 0 0 0 0 0 0 0 0  0
0x8004206A  0018   0 0 0 0 0 0 0 0 - 0 0 0 1 1 0 0 0  1
0x8004206C  1800   0 0 0 1 1 0 0 0 - 0 0 0 0 0 0 0 0  2
0x8004206E  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  3
0x80042070  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  4
0x80042072  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  5
0x80042074  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  6
0x80042076  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  7
0x80042078  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  8
0x8004207A  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  9
0x8004207C  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  A
0x8004207E  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  B
0x80042080  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  C
0x80042082  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  D
0x80042084  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  E
0x80042086  0000   0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0  F
Syser собственной персоной:
7
Миниатюры
Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
30.10.2017, 18:34  [ТС] 6
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

СТРАНИЧНАЯ ОРГАНИЗАЦИЯ ПАМЯТИ

Пришло время разобраться с виртуальной памятью, в основе которой лежит разбиение сегментов на страницы фиксированного размера по 4-Кб. Все линейки NT работают в 'гибридном режиме', когда на сегментную модель накладывается страничная. Такой подход предоставляет диспетчеру памяти полную свободу, и он может более тонко управлять общим пространством, перемещая блоки памяти сместа-на-место. Как-правило, размеры сегментов больше, чем размеры страниц, и ОС имеет отдельные аллокаторы памяти для каждого из слоёв: Global\Virtual\Heap-Alloc.

Аппаратная поддержка страничной организации

Страничная трансляция включается страшим битом(PG) регистра CR0.
На вход транслятора страниц приходит линейный адрес (см.первый пост), который MMU разбивает на 3 части: старшие 10-бит выделяются под каталог страниц (10-бит = 1024 записи), средние 10-бит под таблицу страниц (одна из 1024 страниц), и младшие 12-бит выбирают смещение в странице физической памяти. Страницу физ\памяти называют Physical Frame - страничный кадр, или просто фрейм. Таким образом адресуется глобальное пространство: 1024*1024*4096=4Гб.

Линейный адрес базы каталога-страниц в памяти, определяется содержимым регистра(CR3) 'PDBR - Page Directory Base Register':



У каждой задачи свой каталог-страниц. Он создаётся при построении задачи виндовым загрузчиком. Загрузчик берёт весь бинарный образ программы на диске, и логически разбивает его на 4-Кбайтные страницы. Каждая из страниц нумеруется и отображается в виртуальную таблицу-страниц 'PT - PageTable'. Важно понять, что страницы не копируются с диска в таблицу, а именно отображаются в неё записями.

Физическая память - разделяемый\дефицитный ресурс, и чтобы страницы не валялись без дела в памяти, нужные из них загружаются только по-требованию, а остальные ждут своей очереди на диске. Такой подход позволяет экономить физ\память, которой и так всегда не хватает.

Каждую запись в таблице-страниц называют 'PTE - PageTableEntry'. Не трудно догадаться, что в PTE хранятся базы каждой из страниц. Размер одной записи\Entry равен 4-байта (32-бит), 20 из которых выделяют непосредственно под базу, а раз-уж остаются ещё 12-бит, то разумно использовать их под атрибуты страницы. (запись 'Entry' можно сравнить с дескриптором сегмента - тоже содержимое и пр.., только называются они по другому, хотя инфо-нагрузка та-же).

Для случая, когда образ программы на диске слишком большой, и общее кол-во 4-Кбайтных виртуальных страниц уже вываливаются за края одной таблицы-страниц (всего 1024 записи), имеется т.н. каталог-страниц 'PD - PageDirectory'. В этом каталоге создаётся ещё одна запись 'PDE - PageDirectoryEntry', и в памяти выстраивается вторая таблица-страниц(PT-2) для этой-же задачи. Соответственно выбор конкретной записи в каталоге-страниц напрямую зависит от 10-ти старших бит линейного адреса. В большинстве случаях каталог-страниц содержит всего одну запись, с базой текущей таблицы-страниц, и ОС обходится малой кровью.

Как и в таблице-страниц, в каталоге имеется место под 1024 записи. Ниже представлен формат 4-байтных записей(Entry) каталога и таблицы-страниц. Как видим, в них много общего за исключением того, что в поле 'Base' таблицы-страниц указывается физический адрес фрейма в памяти, а в каталоге - линейная база страничной таблицы:



Манипуляции с мелкими блоками памяти в виде 4-Кбайтных страниц имеет свои преимущества - уменьшается фрагментация памяти, перемещение блоков происходит быстрее и пр. Но для больших объёмов данных волшебная палочка превращается в костыль. Каждое обращение проходит через несколько инстанций от каталога до физической памяти, а это\всё - время..

Учитывая современные объёмы данных, в системах NT+ размеры страниц увеличили до 4-Мбайт. Менеджер памяти может налету переключать размеры страниц, для чего имеется бит 'PSE - Extended Page Size' в регистре процессора(CR4). Трансляция линейного адреса в этом режиме происходит описанным выше способом, только исключается таблица-страниц, а её роль берёт на себя каталог. В результате, под смещение выделяется уже не 12, а 22-бита:



Посмотрим, какое мнение имеет на этот счёт наши 'глаза и руки' - Syser.
Инфу об организации страничной памяти можно выжать из него камандой 'PAGE'.
Только сначала вскормим ему любую тестовую программу, посмотрим на общее кол-во процессов в системе, и на их расположение в памяти - 'ADDR' (системные и юзерские процессы я разделил пробелом):
Код
>addr
Process ID    CR3               EPROCESS Process Name
-----------------------------------------------------
PID = 0x0000  CR3 = 0x00039000  00000000 [System Idle Process]
PID = 0x0004  CR3 = 0x00039000  82BCB830 [System]
PID = 0x0178  CR3 = 0x04EEF000  829CC020 [smss]
PID = 0x01B0  CR3 = 0x06F37000  82985B98 [csrss]
PID = 0x01C8  CR3 = 0x07F3D000  82962DA0 [winlogon]
PID = 0x01F4  CR3 = 0x0897B000  82972398 [services]
PID = 0x0200  CR3 = 0x08A8D000  82936340 [lsass]
PID = 0x0294  CR3 = 0x096D0000  829205B8 [svchost]
PID = 0x02E8  CR3 = 0x09DF8000  828F47C8 [svchost]
PID = 0x0314  CR3 = 0x0A2FE000  828E49F8 [svchost]
PID = 0x037C  CR3 = 0x0A994000  82869620 [svchost]
PID = 0x03D8  CR3 = 0x0BAA9000  82842CA8 [svchost]
PID = 0x0534  CR3 = 0x0E605000  827FF6C0 [explorer]
PID = 0x05B0  CR3 = 0x0FD89000  827F4020 [ctfmon]

PID = 0x0564  CR3 = 0x10B0E000  82527020 [SyserApp]
PID = 0x0420  CR3 = 0x0C0EF000  82838DA0 [RaRegistry]
PID = 0x05C8  CR3 = 0x10450000  827D4780 [RaUI]
PID = 0x049C  CR3 = 0x0758D000  824EE850 [AkelPad]
PID = 0x05B8  CR3 = 0x10111000  827D9B90 [AlfaClock]
PID = 0x05D0  CR3 = 0x10463000  827D4280 [punto]
PID = 0x06EC  CR3 = 0x1385E000  827EE4E8 [Totalcmd]
PID = 0x0710  CR3 = 0x14FBD000  8286F7A8 [Opera]
PID = 0x0684  CR3 = 0x0578B000  81FBB800 [CyberProg]   //--- мой процесс
23 Process(s)
Здесь видно, что в кучу этих процессов замешался мой 'CyberProg.exe', а его каталог-страниц находится по физическому адресу 0х0578B000 (значение регистра CR3). Каждый процесс имеет личный каталог-страниц виртуальной памяти. Теперь смотрим на таблицу страниц моего процесса (т.к. именно он загружен в отладчик). У-гу.. адрес 'PageDir' совпадает, значит это не утка:
Код
>> page
Page Directory Physical 0578B000
Physical     Attributes         Linear Address Range
----------------------------------------------------
05794000     P     A U RW       00000000 - 003FFFFF 
05792000     P     A U RW       00400000 - 007FFFFF
1034B000     P     A U RW       77C00000 - 77FFFFFF   +--> UserPage (U)
08524000     P     A U RW       7C800000 - 7CBFFFFF   |
14D33000     P     A U RW       7F400000 - 7F7FFFFF   |
05790000     P     A U RW       7FC00000 - 7FFFFFFF --+

0003B000     P     A S RW       80000000 - 803FFFFF
00400000     P G D A S RW 4M    80400000 - 807FFFFF
0003E000     P     A S RW       80800000 - 80BFFFFF
0003C000     P     A S RW       80C00000 - 80FFFFFF
01000000     P G D A S RW 4M    81000000 - 813FFFFF
01400000     P G D A S RW 4M    81400000 - 817FFFFF   +--> SupervisorPage (S)
01800000     P G D A S RW 4M    81800000 - 81BFFFFF   |
01C00000     P G D A S RW 4M    81C00000 - 81FFFFFF   |
02000000     P G D A S RW 4M    82000000 - 823FFFFF   |
02400000     P G D A S RW 4M    82400000 - 827FFFFF   |
02800000     P G D A S RW 4M    82800000 - 82BFFFFF   |
02C07000     P     A S RW       82C00000 - 82FFFFFF   |
......                                                |
01052000     P     A S RW       FF800000 - FFBFFFFF   |
0003A000     P     A S RW       FFC00000 - FFFFFFFF --+
totals (467)

U\S = страница юзера или супервизора системы;
A = Accessed - к странице был доступ;
P = Present  - страница присутствует в памяти (может быть на диске);
G = Global   - глобальная страница;
D = Dirty    - грязная\изменённая страница, 
               при выгрузке из памяти её нужно перезаписывать на диск.
               если страница чистая, то перезапись не требуется.
Разбор полёта начнём справа-налево, и со-страниц с выставленным битом(U) - юзерские..
Первая страница моего процесса легла по виртуальному адресу ноль и расплосталась до адреса 0x003FFFFF, а это в аккурат 4Мб. Напомню, что это пользовательское пространство, поскольку лежит в диапазоне 0х7FFFFFFF. Все страницы вплотную прижаты друг-к-другу, и на лицо - выравнивание линейных баз на 4-Мбайтную границу (20-младших бит равны нулю).

Следующие\все страницы так-же 4-Мбайтные, значит ОС использует 4-Кбайтные страницы только при выгрузки их из кэша, во-внешнюю память на диске - 'PageFile.sys'. Системе нет смысла перезаписывать на диск всю 4-Мбайтную модифицированную (грязную'D') страницу целиком. ОС берёт из кэша только 4-Кбайтную часть, и сбрасывает её на диск в виде кластера. Это сокращает время на диалог с тормознутым HDD.

В страницах супервизора нет ничего-нового за исключением того, что ОС активно пишет только в них - все глобальные страницы грязные. Хотя, если-бы моя софтина была не 'HelloWorld', а записывала-бы какие-нить данные (например в переменные), то в них-бы тоже стояла метка (Dirty). Таблица-страниц содержит всего 467 записи, значит умножаем на 4-Мб (размер страницы) и получаем 1.868-Мбайт, т.е. почти всё 2-Гиговое пространство пользователя.

Гораздо интересная часть лога содержится в разделе 'Physical'..
Здесь хранятся базы страниц в физической памяти, т.е. во-фреймах. Отличительной особенность плоской модели памяти является то, что сегменты и страницы могут начинаться с любого адреса, и системе не обязательно их выравнивать на какую-нить границу. Здесь вообще нет границ. Для эффективной работы, выравнивать нужно сам код программы, который потом загружается по виртуальному адресу пользовательского пространства.

Возьмём из лога макс. 'Physical-адрес' 0x14D33000. Это физический адрес со значением 349.384.704, или 333-Мбайт от начала физ\памяти. Поскольку это база страницы, прибавим к ней размер одной страницы(4М), чтобы получить адрес хвоста страницы = 337-Мбайт. Нужно сказать, что именно такого размера ОЗУ у меня установлено на эксперементальной машине: 1-планка 256М, плюс одна 128М, равно 384-Мбайт общей памяти DDR1.
5
Миниатюры
Память компьютера   Память компьютера   Память компьютера  

R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
02.11.2017, 07:52  [ТС] 7
ВИРТУАЛЬНАЯ ПАМЯТЬ

Подобравшись к виртуальной памяти на расстояние вытянутой руки, рассмотрим тонкости её функционирования. На данный момент картина такая., и мы (прикинувшись байтом) находимся внутри 'PageTable'. Справа, друг-на-дружке лежат страничные кадры, а слева - виртуальная память в виде записей PTE. Отмечу, что все секреты виртуальной памяти кроются именно на этом участке архитектуры, а всё\что слева - это аппаратная её реализация. То есть виртуальная память как сущность, есть ничто-иное как записи в таблице-страниц (PTE):



На этой схеме изображена модель памяти систем класса NT (New Technology). C высоты птичьего полёта отчётливо просматривается вся её структура, и транспортный уровень адреса от самого ЦП и до физического пространства ОЗУ. На самом деле, это только внутри-процессорная часть, поскольку на этой схеме отсутствует контроллёр памяти, который преобразует абсолютный адрес, в DRAM-адрес ячеек памяти. На внешнюю шину-адреса, процессор выставляет именно DRAM-адрес (контроллёр памяти встроен в ЦП).

В архитектуре, диапазон функционирования контроллёра памяти наглухо прикрыт аппаратными средствами и программисту не доступен. Он расположен непосредственно между таблицей-страниц и физ\памятью. 32-битный DRAM-адрес ячейки памяти включает в себя: номер модуля, номер банка в этом модуле, номер строки\столбца матрицы памяти, а так-же длинну пакета (поскольку ЦП никогда не читает из памяти 1-байт, а прихватывает в пакетном режиме ещё и рядом-стоящие (64 или 128), которые попадают в кэш процессора). Это отдельная тема, и к виртуальной памяти отношения не имеет. Она сама потянет на постов-так-надцать. Но вернёмся к виртуальной памяти...


Алгоритм загрузки программы с диска.

1. Для создания нового процесса, система выстраивает новый 'РСВ - Process Control Block'. В этот блок скидывается всё окружение процесса - ProcessImage, таблицы IO\Memory\File, и пр. На определённом этапе, создаётся каталог-страниц 'PageDirectory', и его физический адрес загружается в регистр(CR3).

2. Теперь создаётся таблица-страниц 'PageTable', которая описывает виртуальное пространство процесса. Адрес базы этой таблицы, записью 'Entry' заносится в первое поле каталога-страниц 'PageDirectory'. Если общее кол-во страниц больше 1024, то создаётся ещё одна таблица-страниц, и ещё одна запись в каталоге. Образ программы на диске разбивается на 4-Кбайтные страницы, каждая страница нумеруется и ей присваиваются атрибуты.

3. Страницы диска проэцируются в вирт\память процесса записями 'PTE - PageTableEntry'. Кол-во записей в этой таблице, равно кол-ву виртуальных страниц в образе файла на диске. Помимо атрибутов, в каждой из страниц хранится предполагаемый адрес расположения виртуальной страницы в страничном кадре. То есть Physical-адреса баз свободных фреймов в памяти.

4. У всех записей РТЕ сбрасывается "бит присутствия страницы в памяти" (флаг Present=0).
Важно понять, что виртуальное пространство в начале процесса полностью пустое!
Управление передаётся на точку-входа в программу, и первая-же инструкция приводит к 'PageFault' - страничное исключение(#PF).

5. В этот момент, супервизор страниц PUSH-ит CS:EIP (запоминает запрос), и кладёт в регистр процессора(CR2) адрес затребованной страницы. Теперь управление принимает обработчик 'PageFault', который по содержимому CR2 находит эту страницу в записях PTE, и загружает её из дисковой памяти в ОЗУ. На заключительном этапе, супервизор снимает со-стека CS:EIP и просит ЦП повторить запрос, после чего выполнение кода начинается\продолжается в штатном режиме.
-----------------------------

От сюда следует, что никто-ничего заранее не подгружает, а всё загружается через 'PageFault' по-требованию!. Можно с уверенностью утверждать, что безграничное пространство виртуальной памяти толстой цепью привязано к обработчику 'PageFault' - отработавшие и пока не нужные страницы выгружаются из страничного фрейма в файл-подкачки 'PageFile.sys' (они могут ещё пригодиться), а на их место подгружаются новые затребованные страницы.

Теоритически, таким-Макаром можно работать хоть с петабайтными файлами, лишь-бы в ОЗУ было место под пару\тройку дисковых страниц, а остальное организует сам 'PageFault' по записям из PTE. Добрую сотню страниц файла можно отображать по очереди даже в одном страничном кадре ОЗУ, только работать такая машина будет со-скоростью улитки, поскольку всё процессорное время будет уходить на подкачку страниц из диска.


RVA и VA-адреса памяти.

В дизассемблерах и отладчиках можно встретить адреса вида VA и RVA.
RVA-адрес - это 'Relative Virtual Address', или относительный (чего-то) виртуальный адрес. Обычно этот тип адреса используют HEX-редакторы и дизассемблеры, например 'W32Dasm':
Код
Disassembly of File: hWorld.EXE
Number of Objects = 0003h, ImageBase = 00400000h
                           ^^^^^^^^^^^^^^^^^^^^^
   Object01: .text    RVA: 00001000 Offset: 00000200 Size: 00000200 Flags: 60000020
   Object02: .idata   RVA: 00002000 Offset: 00000400 Size: 00000200 Flags: C0000040
   Object03: .data    RVA: 00003000 Offset: 00000600 Size: 00010200 Flags: C0000040

//----------- Program Entry Point -------------
:00401000 6A01                    push 00000001
:00401002 680F304100              push 0041300F
......
Судя по заголовку, секция-кода (.text) программы должна будет лечь по RVA-адресу 1000h, а это как-раз вторая 4-Кбайтная страница от начала. Для секций импорта и данных выделяются ещё по одной странице.

Образ программы загружается по адресу 00400000h вирт\пространства (ImageBase). Занимать нижние адреса никак нельзя, поскольку там находится база 00010000h системных драйверов, и 64-Кбайтная запретная зона системы для вылавливания блох в виде нулевых указателей (64Кб=0FFFFh). Поэтому загрузчик страхуется и отбрасывает базу образа по-дальше. Как видим, все эти области вплотную прижаты друг-к-другу: буфер, драйвера, прикладная задача.

Если сложить Base+RVA, то получим виртуальный VA-адрес, которым и оперирует процессор ('Entry_Point' на скрине выше). Мы опять вернулись к истокам, с чего и начинался весь этот разговор (jmp Post1). В некоторых источниках, виртуальный адрес называют ещё логическим, хотя между ними нет никакой разницы.


Разброс и коллизия страничных кадров

Вернёмся к логу выделенных процессу страниц из предыдущего поста, и посмотрим на диапазон линейных адресов 'Range'. Он принадлежит страницам файла на диске:
Код
>> page
Page Directory Physical 0578B000
Physical     Attributes         Linear Address Range
----------------------------------------------------
05794000     P     A U RW       00000000 - 003FFFFF 
05792000     P     A U RW       00400000 - 007FFFFF
1034B000     P     A U RW       77C00000 - 77FFFFFF
08524000     P     A U RW       7C800000 - 7CBFFFFF
14D33000     P     A U RW       7F400000 - 7F7FFFFF
.....
Первая страница всегда начинается с нуля. Если открыть любую\другую программу в отладчике, то можно увидеть такую-же картину. И в этом нет ничего удивительного, поскольку у каждого процесса своя таблица-страниц и адреса в ней начинаются с нуля. Как было сказано выше, при переключении задач, значение регистра(CR3) перезагружается на базу каталога-страниц новой задачи, чем и объясняется наличие у каждой из них собственной (начинающейся с нуля) виртуальной памяти.

Но посмотрим на адреса физических фреймов 'Physical'. Почему они выравнены не на 4-Мбайтную границу (как виртуальные страницы), а на границу 1000h-байт? (3-младшие тетрады равны нулю, значит 12-бит или 4Кб). Ясно.. Значит в отличии от вирт\страниц, фиизические кадры всё-таки 4-Кбайтные. То есть под одну 4-Мбайтную виртуальную страницу, выделяются сразу 1024 4-Кбайтных фрейма. Вот они замутили.., хотя для выгрузки "грязных" страниц из кэша, это самый оптимальный вариант.

Следующий немаловажный момент, это способ отображения виртуальных страниц на страничные кадры. У первых\двух страниц вроде наблюдается хоть какая-то последовательность, зато третья страница отброшена системой почти-что в хвост физ\памяти. Начиная с четвёртой.., строй вообще нарушается, что приводит к полнейшему хаосу. На выходе, получаем паутину приблизительно такого вида:



Вот она - фрагментация памяти! При таком раскладе, после закрытия приложения система освободит все выделенные процессу ресурсы, и физическая память станет похожа на улыбку хоккеиста с выбитыми зубами. Не радужная перспектива.. Придётся запускать дефрагментатор памяти, который попытается собрать все страничные кадры активного процесса в одном месте, путём перемещения их с поправками в PTE.


Глобальные страницы памяти

Среди общего пула виртуальных страниц, есть страницы с атрибутом(G) - 'GlobalPage'. Эти страницы активно используют драйвера и сама система. Они никогда не выгружаются из фреймов и кэша-TLB, даже при перезагрузке регистра(CR3) в момент переключения задач. Глобальная страница выделена на рисунке выше красным, и к ней могут обращаться несколько процессов для повышения производительности (смотрим на страницы с битом 'G').
Код
>> page
Page Directory Physical 0578B000
Physical     Attributes         Linear Address Range
----------------------------------------------------
08524000     P     A U RW       7C800000 - 7CBFFFFF
14D33000     P     A U RW       7F400000 - 7F7FFFFF

01000000     P G D A S RW 4M    81000000 - 813FFFFF
01400000     P G D A S RW 4M    81400000 - 817FFFFF
01800000     P G D A S RW 4M    81800000 - 81BFFFFF
01C00000     P G D A S RW 4M    81C00000 - 81FFFFFF
.....
Например, механизм прерываний полагается на таблицу(IDT). Если страница с IDT будет выгружена из памяти, то обработка исключения затянется на неопределённое время, или вовсе станет невозможной. Это касается и кода супервизора страниц, который так-же должен быть постоянно закреплён в памяти, иначе подкачка страниц начнёт заикаться. Некоторые страницы требуется закрепить на короткое время, другие должны быть закреплены всегда.

Менеджер виртуальной памяти растасовывает ссылки на глобальные страницы, в таблицы-страниц всех задач в результате чего эти страницы получаются общими. Через них, процессор проникает на ядерный уровень при вызове системных API, и не нужно для этого переключать задачу.
4
Миниатюры
Память компьютера   Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
21.11.2017, 01:04  [ТС] 8
Общие принципы чтения данных из ОЗУ

Не секрет, что при обмене с памятью, ЦП никогда не оперирует байтами, а использует только "пакетный режим". Длину пакета задаёт параметр "BL - Burst-Length". Смысл пакетной обработки в том, что на один адрес столбца контроллёр памяти отзывается чтением сразу нескольких последующих столбцов в строке. Логика DRAM-ядра имеет счётчик наращивания адреса столбцов, который и привязан к параметру "Burst-Length".

Посмотрим на диаграмму ниже.. На ней просматривается значение этого параметра на шине "Data", которое в данном случае равно 4. Контроллёр даже не дожидается окончания чтения первого пакета-данных, и через несколько тактов сразу выставляет адрес следующего столбца, который вычисляется прибавлением значения(BL), к адресу предыдущего столбца. Таким образом, указав всего два адреса, контроллёр читает сразу 8-байтов.


Отдельного внимания заслуживает управляющая линия "Command". Именно она задаёт всем темп, и пинает отстающих. Сигнал "ACT - Activate" приходит вместе со-стробом RAS# и открывает строку. "NOP" - он и в Африке ноп, и представляет из-себя передышку. Заканчивает цикл обмена с памятью команда "Prechange", которая снимает с регистра-защёлки ядра адрес открытой строки, и одним махом отправляет в неё все байты из усилителя "Sense-AMP" - регенерация DRAM-строки памяти. Тонкости работы ядра на аппаратном уровне рассмативаются ниже.


Внутренняя архитектура DDR-SDRAM

Синхронная память "DDR - Double Data Rate" пришла на смену устаревшей "SDR - Single Data Rate". Всю подсистему памяти SDRAM (Synchronous Dynamic Random Access Memory - синхронная динамическая память с произвольным доступом к данным) можно разделить на 3 функциональных узла:

1. Ядро памяти SDRAM. Узел обработки и хранения запоминающих элементов.
Состоит из матрицы 1-байтных ячеек, дешифраторов строк и столбцов, регистров-защёлок адресов, логики управления, и усилителя\буфера "Sense-AMP". По большей части, одинаково для всех типов памяти - как SDR, так и DDR.

2. Буфер ввода-вывода I/O. Служит для промежуточного хранения данных. Именно в буферах кроются основные отличия SDR от DDR2-3-4. Модуль I/O построен на мультиплексоре MUX, который в порядке очереди сливает данные из буфера, для передачи их драйверу внешней шины. (мультиплексоры имеют несколько входов и один выход - чтение, демультиплексоры - наоборот, один вход и несколько выходов - запись).

3. Драйвер внешней шины-данных управляет 64-битной транспортной магистралью от памяти к процессору. Как-правило работает на более высокой частоте, чем частота DRAM-ядра и буферов I/O.

На рисунке ниже, приведены основные отличия трёх поколений DDR. Четвёртое мало чем отличается от тройки (кроме как работа выходных каскадов на более высокой частоте), поэтому здесь она не рассматривается. Как видно, слабым звеном в этой цепочке является само ядро памяти, из-за барьера рабочей частоты - она не может быть больше 200-MHz. Ограничивают её физические свойства конденсаторов динамической памяти. На более высоких частотах мы просто не успеем считать заряд с их обкладок, что приведёт к искажению данных:


Основным достоинством линеек памяти DDR, является т.н. "архитектура 2n-Prefetch", о чём могла только мечтать старушка-память SDR. Во-первых, все узлы SDR работали синхронно на одинаковой частоте, которая не превышала порога в 133-MHz (PC-100,133), а во-вторых - от ядра к буферу была только одна 8-битная линия передачи. Ну и в третьих - у SDR не было дифференциального (второго) клока у драйвера шины. По фронту одного такта можно было передавать только 1-байт данных, чего вполне хватало для писю'шек тех времён.

Другое дело DDR-SDRAM, в которой учли все недостатки SDR. Модернизация началась с того, что от буфера к ядру добавили ещё одну 8-битную шину, и ввели понятие "2n-Prefetch". Два - это две шины к ядру (Double-Data-Rate), "N" - это размер шины (как-правило 8-бит), и "Prefetch" - означает предвыборку данных. Рассмотрим работу памяти по схеме "2n-Prefetch" на примере DDR1..

Весь массив делится на 4 независимых банка памяти (у DDR3 их 8). Каждая из упомянутых выше "2n-шин" соединяются c отдельным банком. Когда контроллёр памяти посылает сигнал активации строки ACT и RAS#, то указанная строка открывается сразу во-всех банках памяти. То есть мы получаем сразу несколько активных строк, и можем чередовать чтение из них. Нужно сказать, что начиная с DDR2, режим чередования банков - "Interleaving Mode" - поддерживается уже на аппаратном уровне.

Доступ к данным ядра осуществляется попарно. Каждая команда чтения приводит к отправке по внутренней 2n-шине, двух байтов. Аналогично и в схеме DDR2.., только шин здесь уже не 2, а 4, и обмен осуществляется в 4-байтном режиме. Именно поэтому длина-пакета(BL) для DDR1 не может быть меньше двух, а для DDR2 - не меньше 4. Из DDR-3 (которая здесь не показана) сделали вообще монстра с ядерной шиной аж "8n", и соответственно банков в ней тоже 8:


Для синхронизации работы буферных регистров с ядром, DDR использует одну и ту-же частоту 200 MHz, хотя выходной "мультиплексор MUX", работает уже на вдвое\большей скорости - 400 MHz, по очереди опрашивая регистры буфера. Эти данные принимает уже драйвер внешней шины, который и передаёт их непрерывным потоком процессору. Дифференциальный тактовый импульс драйвера (второй импульс смещён на пол-такта, см.пред.рис.) даёт возможность передавать данные как по-фронту первого импульса, так и по-фронту второго, переключая входы мультиплексора на удвоеной частоте. Подобным образом работает и DDR-2,3.., только на более высоких частотах.

Диаграммы чтения памяти DDR-1,2 выглядят как на рисунке ниже (без сервисных сигналов). Чтобы не забивать пространство, для DDR-2 указана длина-пакета равная единице, хотя на самом деле, для этого типа памяти она не может быть меньше 4 - т.е. пакетный режим отключён:


Принципиальное отличие DDR3 от 2 заключается в механизме "8n-Prefetch" вместо четырёх. Для его организации, необходимо, чтобы буфер работал на 4-кратной частоте ядра, а мультиплексор - на 8-кратной. Это позволяет за каждый такт памяти снимать с ядра по 8-байт данных, но если учесть пакетный режим (а для DDR3 BL=8), то получается вообще 64-байта, которые через внешнюю шину-данных глобальным пакетом попадают прямиком в кэш-память процессора - "64-byte cache-line".
5
Миниатюры
Память компьютера   Память компьютера   Память компьютера  

Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
21.11.2017, 01:21  [ТС] 9
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

Устройство DRAM-ядра

Поверхностно разобравшись с транспортным уровнем, заглянем внутрь ядра динамической памяти. Запустим любой софт для сбора инфы о железе (например "HWiNFO32") и перейдём в раздел, где указаны данные SPD. Именно в этой крошечной 8-pin м/схеме зашиты все характеристики применяемых в данном модуле чипов. Размер SPD всего 256-байт, и для каждого типа памяти, описание имеет свой формат:
Код
[SPD - Serial Present Detect]
-------------------------------------------------------------
  Memory Module(0)    :   2Gb, PC3-12800, DDR3-SDRAM, SO-DIMM
  Row Address Bits    :   15
  Column Address Bits :   10
  Number Of Banks     :   8
  Number Of Ranks     :   1
  Device Width        :   8 bits
  Bus Width           :   64 bits
Здесь 'Bus' это не автобус, а ширина внешней шины данных - 64 бит (8 байт). Однако размер шины отдельно взятого чипа "Device-Width" равен одному байту (8-бит), значит на модуле установлено всего 8-чипов памяти, которые соединены последовательно (8*8=64бита). Такую комбинацию из 8-ми чипов называют "Memory-Rank" - один ранк памяти. В природе существуют и 2-х ранковые модули, когда на эту-же планку насаживают ещё 8 чипов с обратной стороны модуля - итого 16.

Но вернёмся к логу... Для адресации матрицы каждого из восьми чипов выделяются: 15-бит для строк (Row), и 10-бит для столбцов (Column), а раз так., значит матрица имеет размер: 32768-строки и 1024-столбца (ячейка: 1-байт). Напомню, что это только один чип, а всего их 8. PUSH'-им этот факт и едем дальше...

Смотрим на поле "Number of Banks: 8", которое прямым текстом сообщает, что пространство каждого из чипов разбито на 8 независимых банков (модули до 1Gb имеют 4-банка, свыше - 8). Для их адресации достаточно 3-х бит. Инженеры обозвали эти биты BA[0-2] - Bank-Activate. В организации DRAM-ядра, банки накладываются блоками друг на друга. То есть, 3-банк'овских бита есть ни что-иное, как старшие биты строки. Получаем 18-бит для адресации всех строк матрицы одного чипа, без учёта банков. Итого в одном чипе:
Код
Строк       :  32.768 * 8 банков = 262.144 (18-бит);
Столбцов    :  1024 (10-бит)
Ёмкость чипа:  262144 * 1024 = 268.435.456-байт, или 256-Mb (один чип-памяти).
-------------

            +-+---> Выбор банка(BS)       Диапазон строк
            | |                           ________________
Банк(0)  =  000.111.1111.1111.1111  //--  000000...032767
Банк(1)  =  001.111.1111.1111.1111  //--  032768...065535
Банк(2)  =  010.111.1111.1111.1111  //--  065536...098303
Банк(3)  =  011.111.1111.1111.1111  //--  098304...131071
Банк(4)  =  100.111.1111.1111.1111  //--  131072...163839
Банк(5)  =  101.111.1111.1111.1111  //--  163840...196607
Банк(6)  =  110.111.1111.1111.1111  //--  196608...229375
Банк(7)  =  111.111.1111.1111.1111  //--  229376...262144
                |                |
                +----------------+------> 15-битный адрес строки
Выше упоминалось, что ранк собирается из 8-ми таких чипов. Что будет, если соединить их последовательно плечом-к-плечу? Правильно... кол-во строк останется прежним, а вот кол-во столбцов увеличится в 8-раз. Теперь мы получили глобальную матрицу всего ранка-памяти: 262.144 строк, и 8.192 столбцов. Если перемножить эти значения, то получим размер модуля в байтах: 2.147.483.648 или 2Gb. Именно такую ёмкость имеет планка-памяти на моём ноуте (см.лог HWiNFO32).


Теперь ответим на вопрос: -"Как адресовать 8192-столбцов 10-ю битами?"
Здесь уже интересней... Для согласования с внешней шиной, при сборке модуля шины-данных всех чипов соединяются последовательно, в то время как шина-адреса разводится по всем чипам параллельно. Это важно понять! То-есть 8.192 - это кол-во виртуальных столбцов в глобальной матрице, хотя адресуемых по-прежнему остаётся только 1.024 (10-битный адрес).

Перед тем как выбрать столбец, контроллёру нужно вычислить, в каком из восьми чипов находится этот столбец. Для этого имеются сигналы активации чипов "CS - Chip-Select". Этих сигналов всего 4 - CS[0-3]. Их комбинацией можно выбрать один из 16-ти чипов. Число 16 выбрано не случайно, а с запасом для 2-ранковых модулей памяти, в которых общее кол-во чипов не 8, а 16. Для 1-ранковых модулей, старшая линия(CS) всегда будет сброшена в ноль.

То есть 4-бита, которые используются для выбора чипа, являются старшими битами адреса-столбца. Получили 10+4=14 битный адрес, которым можем адресовать уже не только 8.192 столбцов, но и (Dual-Rank) с его 16.384 столбцами. При этом ёмкость модуля увеличится вдвое: 262144*16383=4Gb
Код
         +--+---> 4 линии(CS)
         |  |                   +--------+---> Диапазон столбцов
Чип(0) = 0000.11.1111.1111 ---- 0000..1023
Чип(1) = 0001.11.1111.1111 ---- 1024..2047
Чип(2) = 0010.11.1111.1111 ---- 2048..3071
Чип(3) = 0011.11.1111.1111 ---- 3072..4095
Чип(4) = 0100.11.1111.1111 ---- 4096..5119
Чип(5) = 0101.11.1111.1111 ---- 5120..6143
Чип(6) = 0110.11.1111.1111 ---- 6144..7167
Чип(7) = 0111.11.1111.1111 ---- 7168..8192
              |          |
              +----------+----> 10-битный адрес столбца
Когда процессор запрашивает у памяти, например, байт из строки(0):столбца(10), контроллёр памяти по номеру столбца автоматом выставляет CS#, активируя буфер I/O чипа ноль, а буферы остальных чипов остаются не у дел. Теперь можно спокойно сливать данные из "Sense-AMP" активного чипа, и передавать их на уровень выше, буферу I/O и далее через драйвер шины - процессору.

Операция чтения начинается с того, что контроллёр памяти выставляет адрес нужной строки, и подтверждает его стробом RAS# - "Row-Address-Strobe". Приняв этот строб, логика ядра открывает нужную строку, но поскольку адресные линии разводятся по чипам параллельно, то указаная строка открывается сразу во-всех чипах памяти. Общую для всех чипов строку называют "страницей DRAM-памяти".

Открытие страницы приводит к тому, что все её байты скатываются в усилители "Sense-AMP" (у каждого чипа свой усилитель). А сколько в одной DRAM-странице байт-то? Нетрудно догадаться, что размер страницы равен общему кол-ву столбцов в данном модуле - 8192.

После того, как эти 8Kб данных благополучно разместятся в буферах 'Sense-AMP', контроллёр выставляет на шину адрес столбца затребованной ячейки памяти, и так-же подтверждает его стробом, только на этот раз CAS# - "Collumn-Address-Strobe". Теперь, логике ядра ничто не мешает выбрать из памяти байт, используя адрес столбца в качестве смещения в буфере 'Sense-AMP', и приступить к передачи пакета данных. При этом, активным остаётся "Sense-AMP" только того чипа, на котором в данный момент присутствует сигнал выбора чипа(CS#). Отключение остальных чипов обрезает DRAM-страницу с 8-ми, до 1Кб.

На рисунке представлена схема чипа DDR-SDRAM (4-банка), где отлично просматривается топология отдельных узлов памяти:


Код
ADD - MA - мультиплексная шина-адреса;
DQi - 8-битная шина-данных чипа.
CLK - Clock - тактовая частота (100..200-MHz);
CKE - ClockEnable - отключение клока для энерго\сберегающего режима;
RAS - строб адреса-строки;
CAS - строб адреса-столбца;
CS# - ChipSelect - активация чипа (раньше было 8-линий, для каждого чипа свой CS#);
WE# - WriteEnable - разрешение записи в чип (открытие вх.буфера);
DQM - DataMask - маскирование отдельных байтов (отключает ненужные DEMUX при записи);
В пакетном режиме работы памяти, DRAM-страница остаётся открытой на всё время чтения пакета-данных. Дальше в дело вступает параметр 'Burst-Length', который определяет длину пакета. Почти на всех современных машинах значение BL=8, что позволяет копить в выходном буфере сразу 64-байта данных за одно обращение (8-раз по 8-байт). Только после этого DRAM-страница закрывается, и данные из всех 'Sense-AMP' опять возвращаются на своё\законное место в строку матрицы - регенерация активной страницы.
3
Миниатюры
Память компьютера   Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
21.11.2017, 01:29  [ТС] 10
Особенности работы контроллёра памяти

Процессор взаимодействует с ОЗУ через контроллёр памяти "МС - Memory Controller". Этот контроллёр отвечает за физическую поддержку модулей SDRAM, а точнее за инициализацию, регенерацию чипов, установки таймингов, выбор тактовой частоты и другие\технические детали. У каждого канала памяти свой МС.

Для сокращения общего кол-ва внешних линий, адресные входы чипов-памяти мультиплексируются. Адрес делится на 2 части. Сначала задаются старшие адресные биты, выбирающие строку массива ячеек. По стробу(RAS#) эти биты сохраняются в регистрах-защёлках чипа. После этого, на те-же адресные линии подаются младшие адресные биты для выбора столбца массива, которые так-же сохраняются в защёлках по стробу(CAS#).

Однако процессор задаёт весь адрес целиком, одновременно помещая все его разряды на шину адреса. Их мультиплексирование выполняется контроллёром памяти. В ответ на запрос обращения процессора к ОЗУ, контроллёр принимает от него полный физический адрес и сигнал определяющий операцию - R/W. Затем он по очереди пересылает в ОЗУ адрес строки и столбца по мультиплексной шине(МА), фиксируя их стробами RAS/CAS соответственно. Шина-данных контроллёру не нужна, поэтому она соединяет процессор и память напрямую:


Таким образом, в дополнение к мультиплексированию адреса, контроллёр памяти осуществляет ещё и генерацию сигналов RAS#, CAS#, CS# и WE#. При использовании чипов DRAM без само-регенерации, контроллёр отвечает ещё и за выдачу сигнала(А10), который управляет процессом регенерации строк матрицы. Сейчас контроллёры освободили от этой задачи - буквально все современные чипы поддерживают регенерацию ячеек памяти по своему внутреннему счётчику, на автомате.


Характеристики модулей памяти

Так уж сложилось, что в 2000-году вместо "конца света", на свет появилась первая память DDR. С этого момента частоту стали разделять на реальную и эффективную. Связано это было с дифференциальным клоком драйвера внешней шины. Маркетинг поспешил воспользоваться этой фишкой и стал на маркировке(PC) указывать не рабочую частоту модуля памяти (как это было у SDR), а его пропускную способность. Чтобы получить полезную нагрузку шины, нужно её разрядность (как-правило 8-байт) умножить на эффективную тактовую частоту:


Из этой таблички видно, что после PC133 сразу-же идёт PC1600. Как такое может быть? 10-кратное увеличение производительности за один шаг! Вот жулики... Это-же прокаченая PC200, которую теперь называют DDR-200. Но поскольку у новоиспечённой памяти были и плюсы в виде архитектуры "2n-Prefetch", то все проглотили эту наживку и успокоились. Ход маркетологов заслуживает апплодисментов!

Помимо этого, модули принято разделять и по форм-фактору:

1. SIMM (Single In-Line Memory Module).
Асинхронная динамическая память. Пусть покоится с миром..
Древний 72-контактный модуль, с односторонним расположением выводов.
На второй стороне контакты дублируются. Устаревший, и давно покинувший рынок вариант.

2. DIMM (Dual In-Line Memory Module).
Могут иметь до 240-независимых пинов (по 120 с каждой стороны).
Применяется во всех современных компьютерах.

3. SO-DIMM (Small Outline DIMM).
Компактный вариант DIMM для ноутбуков. Поддерживает стандарты DDR(2,3).
Популярны 200-контактные модули.

4. Micro-DIMM.
По размерам меньше чем SоDIMM и доступны в вариантах: SDR 144-pin, DDR 172-pin, DDR2 214-pin.
Как-правило применяется в планшетах, и прочих малогабаритных девайсах.

5. RIMM (Rambus In-Line Memory Module).
Форм-фактор модулей типа DR-SDRAM (Direct Rambus SDRAM).
Имеют до 242-контакта, и чаще применяются в серверных платформах.
Из-за высокой стоимости, в РС практически не встречаются.
Особенностью является увеличение частоты за счёт уменьшения разрядности шины.
3
Миниатюры
Память компьютера   Память компьютера  
R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
01.12.2017, 08:20  [ТС] 11
Внешняя шина памяти (системная шина процессора)

Поскольку SDR - Single-Data-Rate, DDR - Double-Data-Rate, то DDR2 должна быть QDR - Quadra-Data-Rate, т.к. данный стандарт подразумевает в 4-раза большую скорость передачи по сравнению с SDR. А ведь термин "QDR" существует-же в доках INTEL. Посмотрим на лог, описывающий характеристики системной шины одной из устаревших мат-плат с чипсетом i845:

Код
Общая информация	 
-------------------------
NorthBridge..:  Intel i845D 
SouthBridge..:  82801BA (ICH2) LPC Controller 

NorthBridge Information
-------------------------
Architecture.:  HUB 
Bus Speed....:  101.0 MHz 
FSB Speed....:  403.8 MHz (QDR)
Почему частоту разделяют на Bus и FSB, и что означает приставка "QDR"?
Ясно, что если разница между Speed'aми 4-кратная и на горизонте маячит поправка QDR (Quadra=4), то между ними явно должна быть какая-то связь. На самом деле "QDR" - это тип системной шины FSB, в которой применяются два дифференциальных клока. Такая схема позволяет передавать 4-байта за такт шины. Нужно сказать, что это не единственный тип в своём роде, но обо всём по-порядку..

Модернизация архитектур МП-систем приводит к расширению функций чипсета, изменяются подходы к его построению. Чипсетам для i286 нужно было всего-лишь связать шину ЦП с несложным контроллёром памяти, и подключить к этой связке шину ISA. Для i486 возможностей ISA уже не хватало, и стали появлятся новые шины.

Процессор соединяется с памятью посредством системной шины FSB - Front-Side-Bus, от пропусной способности которой зависит общее быстродействие системы. На физ. уровне, современная FSB - это 64 дорожки на печатной плате. Ёмкость каждой из дорожек 1 бит - получаем 64-битную шину, по которой в разные промежутки времени передаются адрес и данные (64-бит = 8-байт).


Разнообразие шин в системе

Шины отличаются назначением (внутренняя, интерфейсная), разрядностью (16/32/64-бита), способом передачи информации (последовательный или параллельный), пропускной способностью Мбайт/с, и кол-вом поддерживаемых устройств. Она может быть синхронной (передача только по тактам), асинхронной (передача без привязки по-времени), а так-же мультиплексной (передача адреса/данных по одним и тем-же линиям, по-очереди).

История развития МП-систем доказала, что организация обмена по шинам гораздо важнее, чем особенности процессоров, ведь шины живут намного дольше. Поэтому инженеры ориентируются на уже существующие стандарты шин при разработке своих новых процессоров, т.е. шины оказываются чуть-ли не главным фактором в архитектуре системы.

Ниже приведены характеристики параллельных шин.. Основным параметром шины является пропускная способность в Мбайт/сек (MHz * разрядность шины-данных в байтах). Чем выше этот параметр, тем шина считается производительней, и по ней можно передать больше данных за один её такт:
Код
  Шина        МГц        Мбайт/с     Данные   Адрес
  ----------------------------------------------------
  HT  v3      2000       16000       8-байт   32/64
  FSB 4x      1600       12800       8        32/64
  PCI–E 16х   533/1066   4264/8528   4/8      32/64
  AGP 8x      133/266    1064/2128   4/8      32/64
  PCI         33/66      132/264     4/8      32
  VLB(VESA)   33         132         4        30
  Card Bus    33         132         4        32
  MCA         20         76          4        32
  LPC         16         64          4        32
  EISA        10         33          4        32
  ISA         8          16          2        24
  ----------------------------------------------------
     HT  - Hyper Transport (AMD) Ping-Pong Mode
     FSB - Front Side Bus  (х4 = макс.1600 MHz)
     AGP - Accelerated Graphics Port (2х,4x,8x - множители MHz)
     PCI - Peripheral Component Interconnect (Express)
     VLB - VESA Local Bus
     LPC - Low Pin Count
     MCA - Micro Channel Architecture
     ISA - Industry Standard Architecture (Extended)
На пьедестале видим системную шину HyperTransport с пропусной способностью под 16-ГБайт/c (v2.0), а такую-же позицию с конца - заняла шина ISA, которая в секунду может пропустить через себя всего 16-Mb данных. 1000-кратная разница! А ведь ISA когда-то была системной шиной процессоров 80286. Ясно, что о динамичных видео в то время не могло быть и речи. Она годилась только для передачи текста или игры в "Mario", и на данный момент от неё вообще избавились.

Протоколы шин требуют, чтобы любое из устройств на шине могло:

1. Распознать свой адрес на шине-адреса;
2. Распознать на шине-управления действие, которого ждёт от него ЦП (R/W);
3. Выполнить это действие, и передать результат в ЦП через шину-данных.

Эти три действия составляют один цикл обмена, и называются "шинной транзакацией".
Инициатором транзакаций может быть как сам ЦП, так и любое устройство, способное быть "мастером".


Генератор тактовых импульсов

Теперь сделаем упор на тактовую частоту...
На материнской плате, всё синхронизируется от опорного кварца, который вырабатывает всего одну частоту 25-MHz. Это глобальный метроном для всех устройств в системе. Если какому-то из устройств требуется более высокая частота, то к 25 применяется соответствующий множитель, если-же нужна частота с большей длительностью, то её получают через делитель. Реализуется это ответвлением от опорной линии, с нужным временем задержки. Таким образом порождается вторичный сигнал, который сдвинут по фазе относительно исходного:


Теперь каждой шине можно задать свою частоту: HT, FSB, DMI, PCI-E, PCI, LPC и прочие. На старых платах опорный кварц имел частоту 14,318 MHz, поэтому её оставили для совместительства. Кроме того, девайсы могут иметь свои синтезаторы частот, работа которых должна быть синхронизирована с системными 25-MHz. Ещё нужна "обратная связь" с выхода на вход по всем частотам. Клокер имеет схему сравнения импульсов и если они не равны, значит на шине висит неисправное устройство и шину пора вырубать.

INTEL собирает генераторы тактовых импульсов на м/схеме 9250, или более современном её аналоге 950201. Рисунок демонстрирует общие принципы работы этого генератора:


Роль клокера в системе нельзя недооценивать. К примеру, инструкция ассемблера "HALT" совсем отключает поступление тактовых импульсов на процессор, а в энерго/сберегающем режиме частота системной шины FSB уменьшается в несколько раз, в результате чего ЦП становится неповоротливым и как-бы засыпает.


Эффективные частоты ЦП, памяти и шины FSB

Процессорная шина FSB может работать на физических частотах клокера: 100, 133, 166, 200, 266, 333 и 400 MHz. Эту частоту называют ещё реальной частотой шины процессора. Одну из этих-же частот использует и системная память с процессором. То есть, реальная частота шинного драйвера DDR, системной шины FSB и процессора CPU - всегда одинакова! Иначе они не смогут работать синхронно! Дальше, перечисленные устройства применяют к общей реальной частоте свой множитель (Multiplier), в результате чего все они работают на разных частотах, но с одним периодом.

Для всех плат INTEL множителем FSB является значение(х4), а для памяти - множитель(х2). Это константы, поэтому если эффективная частота FSB=800MHz, а DDR=400MHz, то говорят, что соотношение FSB/DRAM равно 1:1, а не 1:2. Реальная (опорная) частота FSB для этого примера будет иметь значение 200MHz.

Множитель(х4) напрямую связан с типом системной шины FSB. В большинстве случаях - это упомянутая выше шина типа QDR (QPB - Quad-Pumped-Bus), хотя бывают и клинические случаи. Шины первых процессоров Intel были типа GTL, а у AMD - EV6. Для них, множителем будут значения х1 и х2 соответственно. Если сравнивать типы шин FSB с памятью ОЗУ, то шину EV6 можно было назвать DDR, а шину QPB - DDR2. В хвосте осталась-бы GTL, по аналогии с памятью SDR.

Важно!!!
Данный множитель(х4) для шины FSB относится только к платам INTEL,
т.к. шина "Hyper-Transport" его конкурента AMD, функционирует по абсолютно другим принципам.
Пока мы здесь рассматриваем исключительно конструктивные особенности INTEL,
а детали шины AMD будут рассмотрены ниже.


Если реальная частота системной шины ограничена с клокера значением 400-MHz, значит эффективная её частота может достигать макс.порога в 1600-MHz (400х4). Множитель системной шины имеет постоянное значение(х4), в то время как множитель ЦП зависит от типа процессора. Он лежит в диапазоне от х4 до х30 и может быть дробным.

Поскольку в ядре процессора его коэффициент зафиксирован, то реальная частота ЦП зависит от частоты системной шины - при внешнем разгоне шины, повышается и частота процессора. Частоты периферийных шин типа PCI, AGP и прочии, не зависят от частоты FSB, а выходят с клокера отдельными линиями.

Рассмотрим пример, когда реальная частота FSB равна 333 МГц.
Получается, что клокер генерит дефолтные 25-MHz, к которым его внутренние схемы применяют свой множитель: 13,32. Получили физ частоту шины FSB: 333 MHz (25 х 13,32). Теперь к физической, применяем интел'овский множитель шины х4, и получаем эффективную частоту FSB: 1332 MHz, которую и указывает производитель на материнской плате:


Общая формула вычисления эффективных частот на мат\плате выглядит так:

Код
FSB  =  FSB(физ) x4
DDR  =  FSB(физ) x2
ЦП   =  FSB(физ) x (множитель ЦП: 4..30)
------------------------------------------------
Азбука: при FSB(физ) = 333 MHz, множитель ЦП = 9

ЦП  = 333 * 9 = 2997 MHz
FSB = 333 * 4 = 1332 MHz 
DDR = 333 * 2 =  666 MHz
------------------------
FSB/DRAM Ratio = 1:1
Здесь видно, что тактовая частота ЦП напрямую зависит от частоты системной шины. Если изменить её в настройках BIOS (при этом биос лезет в клокер и меняет внутренний множитель FSB), то соответственно изменится и тактовая частота ЦП. Эту операцию называют ещё разгоном - OverClock.

От сюда следует, что если Вы решили обновить память на своей машине, то сначала нужно узнать частоту системной шины и выбирать модуль с частотой, кратной частоте FSB. Например, для указанной выше платы с FSB=1333MHz, идеальным вариантом будет "DDR2-1333 / PC2-10600" (буфер в/в = 667 MHz, см.таблицу в предыдущем посте). Тогда можно будет сказать, что Ваша система максимально оптимизирована по железу.

Множитель ЦП есть величина не фиксированная. Одни производители уменьшают множитель, но повышают частоту FSB, а другие - наоборот. С характеристиками своего процессора можно ознакомиться на сайте https://www.overclockers.ua/cpu/info/:
Код
[System Information]--------------
  CPU Brand  :   Intel(R) Celeron(R) CPU 847 @ 1.10GHz
  CPU Code   :   Sandy Bridge-MB SV  (BGA1023)
  CPU Clock  :   100 MHz
  Multiplier :   8-11

[Processors Frequency]----------------
  Low        :   100.0 MHz х 8  = 800.0 MHz
  Hing       :   100.0 MHz х 11 = 1100.0 MHz
  Current    :    99.8 MHz х 11 = 1097.6 MHz
В этом примере CPU (а так-же шина и память) работает на физ.частоте 100MHz и поддерживает множители 8-11 (Multiplier). Расширеный диапазон множителей (в зависимости от платформы) позволяет процессору работать на частотах от 800 до 1100 MHz.

Но раз есть фронтальная шина Front-Side-Bus, значит должна быть ещё какая-то?
И она действительно существует - это внутренняя шина процессора Back-Side-Bus, которая работает на своей частоте. Эта шина соединяет между собой внутренние узлы самого процессора типа: ядро, кэш-память и прочие. Множитель ЦП как-раз и определяют частоту этой внутреней шины BSB.

Таким образом, производительность шины является одним из важнейших параметров системы, а как стало ясно, заправляет всем генератор опорной частоты, или просто маленький клокер.
3
Миниатюры
Память компьютера   Память компьютера   Память компьютера  

R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
01.12.2017, 08:46  [ТС] 12
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

Сравнение архитектур INTEL и AMD

Конкурентная борьба между двумя гигантами началась ещё в 1982-году с выходом в свет процессора i80286. Именно тогда AMD (Advanced-Micro-Device) подписала контракт с Intel на производство i8086, а уже в 83-году выпустила свой первый Am286 – точный клон i286, но работающий на вдвое большей частоте - аж 20 МГц. Am286 можно рассматривать как первый удар в конкурентной борьбе, которая длится уже 35-лет.

В последующем Intel не раз пожалеет о своей оплошности, поскольку все клоны AMD работали на более высоких частотах, чем такие-же процессоры Intel. Чтобы разорвать этот договор, гигант не придумал ничего лучше, чем начиная с i80586 переименовать свою продукцию на Pentium (от греческого Penta - 5), поскольку контракт был подписан только на цифровую марку. Теперь AMD не могла уже тупо клонировать Intel - так появился AMD-K5 с частотой 133MHz, как первая попытка собственной разработки.

Технически, он был более совершенным чем Pentium, но его недостатком стала низкая частота, поэтому он не смог нанести ожидаемый нокаут Пенте. (есть серьёзное предположение, что литер "К" в названии К5 выбран в честь Супермена, который прилетел с планеты "Криптон". по другой версии - он означает "Kryptonite" - вещество, лишающее Супермена силы. под Суперменом подразумевалась Intel).

Вершиной успеха AMD стал Athlon К7, который нанёс Intel сокрушительный удар! Он был наиболее успешным процессором со времен Am386. В 2000 году в дополнение к интеловскому Р4, AMD выпускает процессор Duron и полностью покоряет бюджетный сектор рынка, оставив Intel далеко позади.

Здесь Intel впадает в глубокий ногдаун, но пробудившись от спячки опять начинает штурмовать процессорный мир со своей новой архитектурой Core-2. На этот раз Intel пошла другим путём и сделал упор не на тактовую частоту, а на более длинный конвейер. Исходя из предыдущего опыта, средства массовой информации с осторожностью отнеслись к рекламе "Core-2", но к разочарованию AMD, он полностью соответствовал заявленным возможностям.

В результате, общая расстановка сил в "турнирной таблице" по году выпуска выглядит приблизительно так (прочерк - прошущеный удар, когда нечем ответить):
Код
                INTEL             |                 AMD
----------------------------------|----------------------------------------
80286       –  12 Mhz, FSB (GTL)  |  Am286         –  20 Mhz, FSB (GTL)
80386       –  33 Mhz             |  Am386         –  40 Mhz
80486       – 100 Mhz             |  Am486         – 120 Mhz
Pentium     – 233 Mhz, FSB (AGTL) |  Am586         – 133 Mhz
  Pro       – 200 Mhz             |  K5            – 133 Mhz
  Xeon      – 233 Mhz             |  K6            – 300 Mhz
  Celeron   – 3.2 Ghz             |  K6-II         – 550 Mhz
  -----                           |  K6-III        – 570 Mhz
Pentium-4   – 3.8 Ghz, FSB (QPB)  |  K7-Athlon     – 1.4 Ghz, EV6
  -----                           |     Duron      – 1.8 Ghz
  -----                           |     Athlon XP  – 2.2 Ghz
Pentium D   – 3.7 Ghz             |     Sempron    – 2.3 Ghz
  -----                           |  K8-Athlon 64  – 2.6 Ghz, HT (1000 Mhz)
Core 2      – 3.2 Ghz, QPI        |     -----
Dual-Core   – 2.8 Ghz             |     -----
Core i7     – 3.2 Ghz             |  K10-Phenom    – 3.7 Ghz, HT (2000 Mhz)
Закон Гордона Мура (1975г) гласит: -"Производительность ЦП должна повышаться вдвое каждые 2 года!", и гиганты приняв его за должное стали просто регулярно увеличивать тактовую частоту своих устройств (на фоне прочих улучшений). Понятно, что бесконечно так продолжаться не могло. При частоте 4-GHz, ЦП начинают работать не стабильно, требуя сложную систему охлаждения. Нужно сказать, что в наше время оверклокеры выжимают из несчастных процессоров космические 8-GHz, при охлаждении их жидким азотом.

Сейчас и Intel и AMD идут уже другим путём - объединяют под одним колпаком несколько ядер. Арифметика простая: чем больше ядер, тем выше производительность, но на практике получается по-разному. Некоторый софт просто не знает, что можно работать с несколькими ядрами, а некоторые - делают это плохо. Только у специально заточенных под многоядерность приложений наблюдается существенный прирост сил.

Посмотрим на такую схему, где в грубой форме определены основные различия архитектур старого и нового поколений. Процессор через FSB подключается к контроллёру системной логики, который обычно называют северным мостом (потом их переименовали в хабы). Он имеет в своём составе контроллёр ОЗУ (сейчас MС встраивают уже в процессор), а так-же контроллёры шин периферии:


Поскольку здесь мы обсуждаем память, то обратим внимание на кочующий образ жизни контроллёров видео и памяти (обозначены синим). На первых платах эти контроллёры были встроены в северный хаб - Graphic & Memory Controller Hub, но под натиском современных требований, системная шина FSB стала проседать не справляясь со-своими обязанностями. Инженерам пришлось перемести контроллёры DRAM и AGP внутрь процессора, чтобы подключить их к более высокоскоростной его внутренней шине.

Это привело к тому, что 3/4 GMCH освободилось, и в него можно сбросить весь южный хаб - получился универсальный Platform Controller Hub, который соединяется с процессором или через последовательную шину DMI (Direct-Media-Interface), или-же более современном её аналоге UMI.

До выхода на сцену AMD-Athlon, в архитектуре AMD не наблюдалось особых новшеств, т.к. это были просто клоны Intel - те же мосты с хабами и прочее. Но с появлением Athlon всё изменилось. Вслед за Intel, AMD так-же перешла к одно-хабовым решениям. Северный мост вместе с интегрированной графикой переехал в ЦП, а южный остался дополнительной схемой. Если Intel предпочитает для новых южных мостов термин "PCH", то в AMD избрали название FCH - Fusion-Controller-Hub, хотя с технической точки зрения чипы обоих производителей похожи друг_на_друга как близнецы.

Одним из главных новшеств платформы AMD-K8 стало внедрение быстрой, двунаправленной параллельно-последовательной шины HyperTransport (HT) для обмена данными между ЦП и остальными узлами системы. Первые её версии работали на частоте 800/1000 МГц, что обеспечивает скорость передачи в 6-8 Гбайт/с. Отличительной особенностью этой шины является то, что её можно использовать и как внешнюю шину процессора, и в тоже время как внутреннюю, для связки нескольких процессоров между собой. Ответный удар от Intel на эту шину последовал чуть-позже. Её назвали QPI - Quick-Path-Interconnect.


Принципы функционирования фронтальных шин

Рассмотрим принципиальные различия системных шин, и способы передачи по ним данных.
Как было сказано выше, на свалку истории отправилось уже приличное их кол-во, начиная от шин типа GTL до относительно недавних FSB. Они прослужили "отечеству" долгое время, поэтому заслуживают хоть какого-то внимания.

Любой процесс в компьютерной системе начинается только фронту тактового синхро\импульса, т.е. по положительной его составляющей. Если тактовый импульс один, то ориентируясь на его фронт можно за такт передать только одну порцию данных. При 64-битной шине это получается 8-байтов за такт шины.

Но если добавить ещё один синхро\импульс и сдвинуть его по-фазе относительного первого, то получим дифференциальный импульс с двумя фронтами, и значит сможем передавать уже вдвое больше данных за такт - первую порцию будем отправлять по фронту клока(1), а вторую порцию - по фронту клока(2). Иногда такой способ называют ещё передачей по обоим фронтам синхро\импульса:


Шина GTL
У системных шин FSB первого поколения типа "GTL - Gunning-Transceiver-Logic" тактовый импульс был один (не было импульса CLK#). Этот тип применялся для работы с памятью Single-Data-Rate (SDR). Поскольку макс.частота 64-битной шины GTL была 100MHz, то пропускная её способность не превышала 800 Мбайт/с.

Шина QPB
Появление памяти DDR потребовало от разработчиков новых типов шин, поскольку из-за GTL возникал эффект "бутолычного горлышка". Всё новшевство заключалось в добавлении сначала ещё одного импульса Clock# (см.рис.выше), а потом к двум - на радостях прибавили сразу ещё два! Так на свет появилась квадро-шина "QPB- Quad-Pumped-Bus" с пропусной способностью х4 (от сюда и постоянный множитель интеловских шин х4). То есть при тех-же 100MHz, QPB передавала уже в 4-раза больше данных - 800х4=3200 Мбайт/с. Если GTL была способна передавать за так всего 8-байт, то QPB уже 32-байта.

Эта шина стала наиболее удачным решением Intel, поэтому просуществовала она достаточно долго, вплоть до появления процессоров Intel Core2. Физическая частота 100MHz для неё не предел - она работала на макс.частоте 333MHz, что определяло её пропускную способность в (333*8)х4=10600 Мбайт/с. На рисунке показано техническое оформление тактовых импульсов на шине QPB (отсчёт ведётся от первого клока):


Шина EV6
Теперь рассмотрим особенности системных шин AMD..
Первые их платформы были точными копиями Intel - это касалось и шины GTL. Но после того, как Intel разорвала в клочья совместный контракт, AMD ввела свою шину "EV6". Эта шина была разработкой компании DEC-Alpha, которая использовала её для своих процессоров "Alpha 21264". Данные ЦП имели кодовое название EV6, что расшифровалось как "Extended VAX" шестого поколения. AMD впервые применила эту шину в чипсете 751.

У неё было всего 2-клока, поэтому она уступала по производительности интеловской QPB. EV6 работала на физ.частотах до 200MHz, ширина шины 72-бита (8-бит для коррекции ошибок ECC), соответственно пропуская способность EV6 была ограничена (200х2)*8-байт=3200 Мбайт/с.

Шина Hyper-Transport
Свет увидел эту шину вместе с процессором AMD-К8. Она стала по истине гипер-шиной всех времён и народов! Козырем был сам способ передачи данных - параллельно\последовательный. Нужно сказать, что в разработке этой шины (помимо самой AMD) принимало участие более (!)140 компаний, которые собрались под одной эгидой "HyperTransport Technology Consortium". Так чем-же HT заслужила такого внимания?

Шина - последовательная, дуплексная (двухсторонняя), ширина 16-бит в одном направлении (в обоих - 32), способ передачи DDR, множители от х1 до х16 (дефолтный 5), физ.частота 200-MHz. Эффективная частота её одной жилы при х5 равна 1000-MHz, хотя в доках указывают HT2000, что определяет результирующую частоту в обе стороны (маркетинг рулит).

Имеется автоопределение ширины-шины в диапазоне 2..32-бита, поэтому она легко масштабируется, позволяя использовать HT не только как внешнюю шину ЦП, но и как интерфейсную шину устройств типа PCI. Для согласования HT и PCI применяются НТ-мосты. Помимо мостов имеются НТ-тунели и свичи, для отвода вторичных жил от основной.

Поскольку шина HT последовательная и двунаправленная (данные могут одновременно передаваться в обоих направлениях - дуплекс), то пропускная способность её вычисляется уже другим способом, а не как у параллельных шин FSB. Шина может работать и в полудуплексном режиме - в этом случае ширина её расширяется до 32-бит. Посмотрим на таблицу ниже..

За такт передаётся два пакета данных (DDR), поэтому для простоты расчётов - ширину умножаем на 2.
Здесь НТ означает встречно\направленную передачу в обе стороны. Соответственно, чтобы получить общую пропускную способность, нужно значение НТ умножить на DDR:
Код
Версия | Год  | МГц(физ)|  Множ | МГц(эфф)|  HT    | Ширина | DDR    | Гбайт/сек
-------|------|---------|-------|---------|--------|--------|--------|----------
1.0    | 2001 |  200    |  х4   | 800     |  1600  | 32     | 8-байт | 12.8
1.1    | 2002 |  200    |  х5   | 1000    |  2000  | 32     | 8      | 16.0
2.0    | 2004 |  200    |  х7   | 1400    |  2800  | 32     | 8      | 22.4
3.0    | 2006 |  200    |  х13  | 2600    |  5200  | 32     | 8      | 41.6
3.1    | 2008 |  200    |  х16  | 3200    |  6400  | 32     | 8      | 51.2
Как-правило в биосе платформы AMD есть опция "Hyper Transport Frequency", которая меняет множитель. Будьте осторожны с этой опцией! Для большинства систем, штатного множителя х5 хватает за-глаза - при этом получаем НТ2000. Поскольку контроллёр памяти во-всех современных платформах интегрирован непосредственно в процессор, частота шины "HyperTransport" мало влияет на быстродействие системы.

При увеличение частоты НТ задираются и частоты периферийных шин, что может отрицательно повлиять на такие устройства как SATA, PCI-Express и прочии. В сети достаточно примеров, когда оверклокеры увеличив частоту НТ - теряли при этом данные на харде.

При множителе х5 (несмотря на относительно низкую пропускную способность 16-Гбайт/с) - HT её вполне хватает, ибо самое узкое место - контроллёр ОЗУ, вынесен за пределы шины внутрь процессора. Увеличение скорости работы шины (связывающей ЦП с чипсетом), важно только для машин с несколькими видео-картами. В этом случае карты начинают делить между собой пропускную способность шины PCI-E, поэтому есть резон чуть прибавить её частоту.

Шина QPI (Intel)
..была разработана в 2008г для замены традиционной шины FSB. "QPI - QuickPath Interconnect" была призвана бросить вызов шине "Hyper-Transport". Используется для связи ЦП с чипсетом, но если платформа многопроцессорная - то и для связки нескольких ЦП друг с другом. Как и НТ - является последовательной, двунаправленной шиной и подразумевает, что контроллёр памяти встроен в ЦП.

Ширина в каждую сторону (приём-передача) составляет по 20-бит (20 отдельных пар линий), при этом 16-бит отводится для передачи данных, 2 линии резерв для сервисных сигналов, и ещё 2 - для коррекции ошибок CRC. C учётом ещё двух пар линий тактовых импульсов (одна пара на приём, другая на передачу), получаем 42-пары линий. То есть QPI является 84-битной.

Шина может работать на частотах от 2,4 до 4,8 GHz. Пропускная способность составляет 25,6 Гбайт/с в одну сторону, хотя для шин QPI и НТ такую единицу измерения теперь не применяют. Вместо неё введён термин "трансферов в секунду", т.е. число передач пакетов в секунду - GT/s (гиго-транзакаций).
---------------------------------

Выводы..
AMD, и Intel - это разные архитектуры и поэтому сложно их сравнивать. Анализ эффективности каждого процессора AMD и Intel, это не очень хорошая идея, поскольку мы не можем со 100% уверенностью сказать, что конкретная модель Intel лучше, чем другая модель от AMD только потому, что у неё более высокая тактовая частота.

Как-правило, скорость Intel всегда выше, чем у AMD.. Но это не означает, что процессоры Intel лучше. Высокая скорость совершает больше рабочих циклов в секунду, а не больший объём работы. У Intel есть тенденция делить задачу на множество мелких частей для более лёгкой обработки, поэтому объём работы за цикл относительно невелик. В отличие от Intel, у AMD рабочий цикл длится дольше, но он обрабатывает больше данных за такт. Таким образом, когда AMD суммирует общий объём проделанной работы, то результат получается довольно большим.
5
Миниатюры
Память компьютера   Память компьютера   Память компьютера  

R71MT
8574 / 1636 / 328
Регистрация: 29.07.2014
Сообщений: 2,679
Записей в блоге: 5
12.05.2018, 11:32  [ТС] 13
Лучший ответ Сообщение было отмечено Mikl___ как решение

Решение

Пора-бы уже поставить тут жирную точку и закрыть этот пост, но осталась ещё нераскрытая тема - это устройство кэш-памяти. Как и все/скоростные устройства, кэш глубоко зарыт внутри ЦП и как он функционирует на самом деле, наверняка знают только его разработчики. В манах вопрос освящается мутно и не хватает простых примеров, чтобы распутать сложные понятия - посмотрим на кэш с другой стороны..

Кэш-память процессора

Работа кэш основана на принципе локальности обращений. Это уникальный механизм, способный предсказывать запросы к памяти более чем в 90% случаях, и это при соотношение размеров 1:100000 (4Gb/32Kb). Как показала практика, в любой момент времени программы используют только часть своего кода, которая реализует одни и те-же операции с несколько отличающимися данными. Затем переход к другой области памяти, и всё идёт по-кругу. Такое положение объясняется наличием циклов в коде, что играет кэшу на-руку.

Ещё с рассвета архитектур, ЦП общается с памятью посредством параллельной шины. Остальные девайсы переходят уже на более высокоскоростной последовательный интерфейс (PCIe, USB3), однако шина памяти остаётся прежней - так было и будет, пока инженеры не придумают что-то взамен динамической ОЗУ. Именно DRAM тормозит весь тех/процесс, т.к. её ядро не способно превысить частотный барьер в 200 MHz - на более высоких частотах конденсаторы ячеек просто не успевают разряжаться. Динамическая DRAM хоть и тормознутая - зато большая и дешёвая, это и удерживает её позиции на рынке.

Чтобы хоть как-то решить проблему DRAM, было решено добавить между процессором и ОЗУ небольшую прослойку в виде статической кэш-памяти SRAM, где запоминающим элементом служит уже не конденсатор, а триггер. Регистры самого процессора собираются на таких-же триггерах, поэтому скорость обмена ЦП с кэш-памятью имеет коэффициент 1:1.
----------------------------------------

В наше время, все операции с памятью выполняются только в пакетном режиме, процессор не может записать в ОЗУ байт или слово, он загребает за-раз сразу по 64-байта (шина=8, и счётчик BL=8), которые отправляет в свой кэш - '64-byte cache line'. Именно такой размер кэш-строки присущ буквально всем современным процессорам.

Ясно, что в кэше хранится не одна строка, они собираются в блоки из N-строк - один такой блок называют банком кэш-памяти, или на их манер 'Way', каждая строка имеет свой индекс. Кол-во строк в одном наборе зависит от ёмкости кэш, и лежит в диапазоне от 32 до 8192. На рисунке ниже представлен банк из 64 кэш-строк. Если в одной строке 64-байта, а всего строк тоже 64, то такой кэш способен отобразить одну 4-Kбайтную страницу памяти (64x64=4096):

Память компьютера


Инженеры распилили общее пространство кэш на две части: в первой хранятся непосредственно кэш-строки, а во второй - их адреса. Адресное поле назвали тегом 'TAG', в которое сбрасывается не весь 32-битный адрес строки, а только старшая его часть. У каждой кэш-строки свой тег, разрядность тега зависит от размера и организации кэш - чем больше кэш, тем меньше битов в теге. То есть теговая память кэша(L1) будет размером больше, чем теговая память кэша(L2).

В глазах кэша, мир существует в виде страниц физической памяти. Когда кэш смотрит на 4Kb страницу, то по индексу[0] он отображает у себя её байты 0-63, по индексу[1] - байты 64-127 и т.д. Такой шаблон повторяется для каждой страницы, поэтому данные третьей строки на странице[0], будут отличаться от данных такой-же строки на странице[1]. Но постойте... А куда мы собираемся отображать страницу[1] - в кэш-же пока имеется только 1-Way для нулевой страницы?

Обстоятельства вынуждают нас добавить в структуру кэш ещё один Way, ..но раз-уж есть такая возможность, то добавим не один, а сразу 7-штук! Тогда получим заявленную производителями организацию '8-way cache'. Если в одном наборе(Way) мы могли отобразить одну страницу памяти, то теперь восемь - а это 32Kb памяти:

Память компьютера


Посмотрим на характеристики процессоров Intel из отчёта CPU-Z...
Здесь видно, что каждое ядро процессора имеет свой кэш. Раздельные кэши для инструкций и данных имеет только L1. На всех уровнях L1-L2-L3 его организация отличается как по ёмкости, так и по кол-ву наборов(Way) в диапазоне 4..16. Вот тут-то и начинается самое интересное:
Код
Name             Intel Core i5 3230M
Codename         Ivy Bridge  (2-ядра)
Technology       22 nm
L1 Data cache    2 x 32 Kb,  8-way set associative, 64-byte line size
L1 Inst cache    2 x 32 Kb,  8-way set associative, 64-byte line size
L2 cache         2 x 256 Kb, 8-way set associative, 64-byte line size
L3 cache         3 MBytes,  12-way set associative, 64-byte line size
--------------------------------
Name             Intel Core i7 6700K
Codename         Skylake      (4-ядра)
Technology       14 nm
L1 Data cache    4 x 32 Kb,  8-way set associative, 64-byte line size
L1 Inst cache    4 x 32 Kb,  8-way set associative, 64-byte line size
L2 cache         4 x 256 Kb, 4-way set associative, 64-byte line size
L3 cache         8 MBytes,  16-way set associative, 64-byte line size
Изменчивый характер структуры кэш, тянет за собой модернизацию всей (ответственной за работу кэш) аппаратной части процессора. В зависимости от ёмкости, наборы Way меняют свой облик, добавляя или уменьшая кол-во индексов в своей тушке. Если 32Kb кэш организован как 8-Way в каждом из-которых по 64 индекса, то общее кол-во 64-байтных строк в таком кэш будет равно: 64*8=512, а общая ёмкость: 512*64-байт=32Kb. Организацию любого кэш можно вычислить по определённой формуле, посмотрим на неё:
Код
32Kb L1-cache (8-way)------------------------
     32Kb / 64-byte = 512 всего кэш-линеек
      512 / 8-way   =  64 индекса в одном наборе Way

CPU address: Offset = 6-бит для выбора одного из 64-байтов в строке
             Index  = 6-бит для выбора одного из 64-индексов
             Tag    = 20-бит (старшая часть адреса)

256Kb L2-cache (4-way)-----------------------
    256Kb / 64-byte = 4096 cache line
     4096 / 4-way   = 1024 index

    Address: Offset = 6-bit
             Index  = 10-bit
             Tag    = 16-bit

8Mb L3-cache (16-way)------------------------
      8Mb / 64-byte = 131072 cache line
   131072 / 16-way  = 8192 index

    Address: Offset = 6-bit
             Index  = 13-bit
             Tag    = 13-bit
Память компьютера


Рассмотрим детали реализации подробней...
Длинна кэш-строки постоянна и равна 64-байтам. Для выбора одного из байтов строки требуется 6-бит - это младшие биты адреса, который процессор выставил на шину. В то-же время разрядность поля индекса уже не так постоянна, и зависит от ёмкости кэш и наборов(Way) в нём. Оставшиеся старшие биты адреса отправляются прямиком в теговую память. Посмотрим на следующий рисунок, где для тега выделяется 20-бит (типичный L1-кэш ёмкостью 32Kb)..

Память компьютера


20-битный тег подразумевает выравнивание страниц памяти на 4Kb границу, поскольку младшие 12-бит адреса логически сбрасываются в нуль. Чтобы скоростной кэш не превратился в тормознутый флоп, при помощи аппаратного бит-теста поиск осуществляется одновременно во-всех 512-ти тегах буквально за 1 такт. Только в случае попадания в тег, контроллёр снимает с адреса индексную часть и приступает к проверке всех кэш-строк в данном банке Way, иначе запрос перенаправляется кэшу сл.уровня.

Очередным кэшам приходится уже туговато, у них теги меньшей разрядности, а значит им предстоит иметь дело уже не с страницами, а с сегментами - соответственно перебирать приходится уже больше индексов в банке(Way). Например 16-битный тег кэша(L2) очищает младшие 16-бит адреса, что вынуждает кэш работать уже с блоками, размером 64Kb. Блоки 8-метрового кэша(L3) выравниваются вообще на пол-метра, поэтому их индексация занимает больше времени. Младшие 6-бит адреса в поиске не принимают участия - в случае кэш-попадания, по их содержимому выбирается конкретный байт из Cache-Line.

Передача запроса на уровень ниже (L1->L2->L3->Mem) может осуществляться двумя способами. В первом случае, запрос отправляется сразу всем оппонентам одновременно - это т.н. широковещательный запрос 'Look-Aside'. Если выстрел попал в L1, то запросы к остальным снимаются - в этом случае говорят о кэш-попадании (Cache-Hit). Если-же случился промах (Cache-Miss), то запросы к L2-3 снимаются поочерёдно, пока запрос не достигнет памяти ОЗУ. Вариант хороший, только съедает много энергии. Альтернативой ему служит вариант 'Look-Through', когда обращения начинаются только после фиксации кэш-промахов. При этом теряется всего 1-такт, зато экономится энергия.


Оранизация кэш

В природе мирно сосуществуют 3 способа отображения памяти в кэш: кэш прямого отображения 'Direct-Mapped', полностью ассоциативный кэш 'Fully-associative', и их комбинация - наборно-ассоциативный кэш 'Set-associative'. Сейчас на всех уровнях применяется только 'Set-Cache', поэтому не будем забивать себе мозги, а рассмотрим только его.

В архитектуре 'Set-associative', все строки каждого из банков(Way) делятся на несколько наборов(Set). Если в банке имеем 64-строки, то их можно условно поделить на 2-набора, по 32-строки в каждом:

Память компьютера


Когда такой кэш отображает в себе память, он будет пытаться поместить первые 32-строки каждой из страниц, только в свой набор Set(0). Для следующих 32-х строк страницы-памяти, отводится уже место в наборе Set(1) и т.д. То-есть строка(20) любой из страниц памяти не может попасть в набор(1), а только в набор(0) - в этом и заключается ассоциативность. По мнению кэш-контроллёра, искать строки при такой организации проще, чем когда они переплетаются в непонятный клубок - ему виднее..

Однако своё мнение на этот счёт имеет не бритый 'Fully-associative cache', который беспорядочно кидает строки в любую/свободную область банков Way (кто первый, того и тапки). 'Direct-Mapped' относится к порядку уже чуть лояльней, он поддерживает нумерацию и загружает только те строки, номера которых соответствуют его номерам один-к-одному. Таким образом, рассматриваемый нами 'Set-associative cache' впитал в себя всё/лучшее своих предшественников и сдавать позиции не намерен.

Политика замещения данных в кэш

Ясно, что организация кэш требует смотрящего, который с высока следил-бы за порядком и препятствовал случайной перезаписи уже хранящиеся в кэш данных. Контроль осуществляется посредством 4-х бит, два из которых являются значимыми - бит(М) 'Modified cache-line', и бит(V) сигнализирующего, что кэш-строка занята и кому-то принадлежит 'Valid cache-line'. Эти биты добавляются старшими в тегах кэш-строки.

Бит-модификации даёт контроллёру знать, нужно-ли перезаписывать в ОЗУ строку перед выгрузкой её из кэш-памяти. Такая дилема возникает у него только в двух случаях: (1)когда процессор встречает инструкцию очистки кэша с выгрузкой строк WBINVD - Write-Back Invalidate cache, (2)при обычных обстоятельствах для поддерки когерентности кэш с оперативной памятью (остальные ситуации вытекают из этих/двух). В свою очерель бит-валидности указывает на то, что на данный момент кэш-строка действительно отображает соответствующую строку памяти, и её нежелательно выталкивать или перезаписывать новой строкой.

Память компьютера


Размеры кэша и ОЗУ сильно отличаются, поэтому неизбежно наступает момент, когда придётся освободить одну из кэш-строк, чтобы загрузить на её место новую. Алгоритмы замещения стары как-мир и плавают на трёх китах: случайный RANDOM - орёл или решка, FIFO - становимся в очередь, и LRU - редко используемая строка. Первый неэффективен, зато прост в реализации. Второй - более надёжный, но оставляет желать лучшего. Третий - требовательный к ресурсам, зато наиболее результативный - его и применяют в современной кэш-памяти. Биты V/M были введены в тег специально для поддержки работы алгоритма LRU.

Поддержка когерентности

Бывают ситуации, когда программа работает с внешним устройством, и это устройство ждёт каких-либо данных от программы. Процессор грузит исполняемый код в свой кэш, подготавливает данные, после чего сообщает девайсу, что запрос готов. Устройство обращается к памяти и... данных там не находит. Почему? Всё просто - данные-то есть, только остались они в кэш-памяти, и ЦП не побеспокоился о своевременной выгрузки их в ОЗУ. Такая ситуация носит проблемный характер, а её решение назвали "Поддержкой когерентности".

В идеальном случае, отмеченные битом(М) изменнёные кэш-строки нужно выгружать в ОЗУ сразу после их модификации. Тогда проблем с когерентностью не будет, зато возникнет другая проблема - жуткие тормоза, поскольку процесс требует записи в неуклюжую память. Если программе приспичит менять данные через короткие промежутки времени, тогда ЦП только и будет делать, что записывать данные в ОЗУ, а мы сможем высушить вёсла за это время. Значит такой подход для кэша не преемлен - решать проблемы когерентности выпало на плечи двух политик записи в ОЗУ:

Write-Through - подразумевает сквозную записью модифицированных кэш-строк. С данной политикой солидарен кэш(L1). Как только строка получает бит(М), она сразу копируется в кэш(L2) - задумчивость тут не прощается. L1 снимает с себя обязанность по разбору грязных строк, и озадачивает этим кэши следующих уровней.

Write-Back - альтернатива первой. Она придерживается правил отложенной записи (М)строк. Для их хранения, современный кэш-контроллёр имеет не один, а целых четыре "буфера отложеной записи", организованых по-принципу FIFO - первым пришёл, первым выйдешь. Когда при записи возникает попадание в кэш, эти буферы сразу обновляются. Контроллёр ждёт освобождения шины-памяти (её могут занять устройства c DMA), и при первой-же возможности информирует об этом ЦП. Только теперь тот уверен, что шина свободна и можно воспользоваться ею для циклов записи модифицированных строк в основную память.

Ознакомится с текущими политиками можно запросив отчёт у 'PC-Wizard'.
Нужно сказать, что ни каждый софт их показывает, но если кого заинтересует, то вот:
Код
>> Процессор
      Type            : Intel Celeron D  336J, сокет 775
      Кодовое имя     : Prescott

  > Data Cache L1     : 16 Кб,  8-way set-associative, 64-byte line
      Режим записи    : Write-Through
      Number of Sets  : 32

  > Кэшe L2           : 256 Кб, 4-way set-associative, 64-byte line
      Режим записи    : Write-Back
      Number of Sets  : 512
Таким образом, буферы отложенной записи позволяют на некоторое время откладывать фактическую запись в основную память. В последних процессорах политики могут комбинироваться на-лету 'Write-Combining'. Запись буферизуется во-всех режимах работы ЦП, исключение составляет лишь запись в порты ввода/вывода устройств.

Некэшируемые регионы памяти

Нужно сказать, что не всякую область памяти можно кэшировать. Есть участки, которые и силком не загонишь в кэш - для них кэширование принципиально недопустимо. К таким участкам можно отнести, например разделяемую память адаптеров. Если кэшировать такие области, то обязательно всплывает наружу проблема когерентности кэш. Кроме того, кэширование полезно отключать при выполнении однократно исполняемых участков программы (например, инициализации) с тем, чтобы из кэша не вытеснялись более полезные фрагменты кода. Когда процессор натыкается на некэшируемый регион памяти, все обращения R/W перенаправляются сразу на системную шину. Такой тип требуется для ввода-вывода посредством MMIO (Memory Mapped I/O).

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

Регионы и методы кэширования зависят от возможностей конкретного ЦП. Как-правило программируются они через набор его регистров 'MTRRs - Memory Type Range Registers' (регистры свойств областей памяти), или внутри таблицы 'PAT - Page Attribute Table' (таблица атрибутов страниц памяти):

Память компьютера


Буфер странслированных адресов TLB

Ещё одной разновидностью кэш-памяти является ассоциативный буфер TLB - Translation Lookaside Buffer. Этот кэш-буфер во многом похож на кэши(L1.2.3), за исключением одной поправки - в нём нет места для данных. Кэш предназначен для хранения только адресов последних затребованных страниц виртуальной памяти. Если транслятор страниц отключен в блоке MMU процессора, то TLB так-же отключается. Прозрачен он и в реальном режиме.

Имеются три раздельных буфера TLB для хранения адресов 4K,2M и 4M-байтных страниц соответственно. Средняя ёмкость - 64 индекса для 4-Кбайтных страниц, что позволяет мгновенно сформировать физический адрес только для 256Kb основной памяти (64х4). При этом по статистике, вероятность кэш-попаданий в TLB составляет 98%, т.е. только в 2-х случаях из 100 будут промахи:

Память компьютера


Сути в том, что на трансляцию адреса виртуальной страницы уходит много времени. Сначала нужно опросить регистр(CR3), чтобы определиться с базой каталога страниц(PDT); потом просканировать каталог страниц(PT); ..и наконец в таблице(РТ) найти запись(PTE). Такой караван проверок отрицательно сказывается на производительности системы, поэтому использовав адрес страницы один раз, процессор запоминает его в страничном кэше TLB.

В следующий раз, когда процессору потребуется страница, он опрашивает и таблицу и кэш одновременно, и если происходит кэш-попадание, то получаем прирост скорости за счёт обхода этапа трансляции - адрес уже готовый. Кому всё побарабану - так это 12-битному оффсету, которому в этом театре-действий выпало играть роль массовки - поле предназначено для выбора смещения внутри найденной/4-Кбайтной страницы памяти.
---------------------------------------------------

Задраиваем люки..

Считаю, что для одной темы букаф напечатано уже предостаточно, и пора прекращать сие повествование. Если найдутся неточности, то буду рад услышать разумное их опровержение. В подборе и оформлении материала принимали участие:

0. Google
1. Intel Software Manual volume 1,2,3
2. Встроеные средства WinXP
3. Программы сбора информации: PC-Wizard, Dr.Hardware, HWiNFO-32
4. НЕХ-редакторы: WinHEX, HxD, Hiew
5. Редакторы: Word, Exel, Photoshop, EditPlus
6. Горячительные напитки - по вкусу..
5
12.05.2018, 11:32
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.05.2018, 11:32

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

Память компьютера. (Сегмент, смещение и т.д.)
Приветствую! Вот чего-то я совсем заплутал. Разбирался по этому Потыкайте отвёрткой: 1....

Ввод матрицы в память компьютера
Добрый вечер участникам форума. Я много лет писал на делфи. Сейчас обстоятельства сложились так...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru