Тема 7. Система Процессор-Память
Поток данных Процессор-Память
При работе процессор загружает нужные данные из памяти, делает операции с ними и выгружает обратно в память. При этом возникает поток данных Процессор-Память ( анг. Memory Traffic ).
Кеш процессора
Для ускорения операций чтения памяти используют кеш процессора. Кеш процессора - это буффер, в котором запоминаются данные последних ячеек памяти, к которым происходил доступ. При этом если при следующем обращении данные нужной ячейки памяти имеются в кеше - они берутся оттуда, а не из памяти. Так как кеш работает намного быстрее памяти - скорость доступа значительно выше.
Кеш - быстродействующая память, но она дорога в изготовлении и поэтому её объём небольшой.
Нельзя программировать размещение данных в кеше, но можно программировать создавая условия для размещения их в кеше.
Регистры процессора
Регистры процессора - несколько специальных ячеек памяти ( по нескольку байт, обычно Целочисленные в соответствии с разрядностью процессора, а FP - 10 байт ). Регистры располагаются в самом процессоре поэтому являются самими быстрыми ячейками памяти. Процессор напрямую оперирует данными в регистрах.
Так например при сложении двух целых числа они вначале загружаются соответственно в два регистра. После того процессор складывает содержимое одного регистра с другим и размещает сумму в одном из них. После того сумма из регистра выгружается в оперативную память.
Архитектура | Целочисленные | FP |
---|---|---|
x86-32 | 8 | 8 |
x86-64 | 16 | 16 |
Itanium | 128 | 128 |
Команды процессора позволяют размещать переменные сразу в регистрах. Так например в циклах переменные-счетчики могут "жить" в регистрах - ведь их конечный результат после работы цикла не нужен.
Так как количество регистров невелико - только часть переменных может быть расположена в регистрах.
Оптимизация
При создании испонимого кода компилятор оптимизирует код на повышение скорости его работы ( или иногда если нужно на его размер ).
Пример оптимизации:
Для кода
class Program
{
static void Main()
{
String s1 = "";
for( int i = 1; i <= 10; i++ )
{
String s2 = Console.ReadLine();
s1 += s2;
}
System.Console.WriteLine( s1 );
}
}
можно ожидать следующее:
- Код будет скомпилирован из языка в C# в язык CL без оптимизации ( ведь CL - общий язык и оптимизировав его для одной платформы он не будет оптимизирован для другой );
- При запуске код CL будет скомпилирован и оптимизирован компилятором JIT в исполнимый код процессора;
- При оптимизации переменные s1, s2, i скорее всего попадут в регистры;
- Строки, которые будут содержать s1 и s2 не попадёт в регистры ввиду большого размера.
- Так как s1, s2 - ссылочные типы, сами значения - адреса ячеек памяти где располагается текст смогут попасть в регистры. А сам текст остаться в памяти.
Аппаратный стек
Аппаратный стек организуется как выделенная область памяти, управляемая самостоятельно процессором. При вызове функции в стек записывается адрес возврата и аргументы функции. При возврате функция считывает адрес возврата из стека и производит переход по этому адресу.
Локальные переменные типа значения создаются в стеке. При этом при выходе из функции стек чистится автоматически и сборку мусора выполнять не нужно.