+ неправильный бит четности 4 (биты 4, 5, 6, 7, 12, 13, 14, 15, 20, 21 содержат пять единиц);
♦ правильный бит четности 8 (биты 8, 9, 10, 11, 12, 13, 14, 15 содержат две единицы);
♦ правильный бит четности 16 (биты 16, 17, 18, 19, 20, 21 содержат четыре единицы).
Общее число единиц в битах 1, 3, 5, 7, 9, И, 13, 15, 17, 19 и 21 должно быть четным, поскольку в данном случае используется проверка на четность. Неправильным должен быть один из битов, проверяемых битом четности 1 (а именно 1, 3, 5, 7, 9, И, 13, 15, 17, 19 и 21). Бит четности 4 тоже неправильный. Это значит, что изменил значение один из следующих битов: 4, 5, 6, 7, 12, 13, 14, 15, 20, 21. Ошибка должна быть в бите, который содержится в обоих списках. В данном случае общими являются биты 5, 7, 13, 15 и 21. Поскольку бит четности 2 правильный, биты 7 и 15 исключаются. Правильность бита четности 8 исключает наличие ошибки в бите 13. Наконец, бит 21 также исключается, поскольку бит четности 16 правильный. В итоге остается бит 5, в котором и кроется ошибка. Поскольку этот бит имеет значение 1, он должен принять значение 0. Именно та-
Рис. 2.12. Построение кода Хэмминга для слова 1111000010101110 добавлением к битам
данных пяти контрольных разрядов
Чтобы найти неправильный бит, сначала нужно подсчитать все биты четности. Если они правильные, ошибки нет (или есть, но ошибка не однократная). Если обнаружились неправильные биты четности, нужно сложить их номера. Сумма, полученная в результате, даст номер позиции неправильного бита. Например, если биты четности 1 и 4 неправильные, а 2, 8 и 16 правильные, то ошибка произошла в бите 5(1 +4).
Кэш-память
Процессоры всегда работали быстрее, чем память. Так как процессоры и память совершенствуются параллельно, это несоответствие сохраняется. Поскольку на микросхему можно помещать все больше и больше транзисторов, разработчики процессоров создают конвейерные и суперскалярные архитектуры, что еще больше увеличивает быстродействие процессоров. Разработчики памяти обычно используют новые технологии для увеличения емкости, а не быстродействия, что делает разрыв еще большим. На практике такое несоответствие в скорости работы приводит к тому, что, когда процессор обращается к памяти, проходит несколько машинных циклов, прежде чем он получит запрошенное слово. Чем медленнее работает память, тем дольше процессору приходится ждать, тем больше циклов проходит.
Как мы уже отмечали, есть два пути решения проблемы. Самый простой из них — начать считывать информацию из памяти и при этом продолжать выполнение команд, но если какая-либо команда попытается использовать слово до того,
как оно считано из памяти, процессор должен приостановить работу. Чем медленнее работает память, тем чаще будет возникать такая ситуация и тем больше окажется время простоя процессора. Например, если отсрочка составляет 10 циклов, весьма вероятно, что одна из 10 следующих команд попытается использовать слово, которое еще не считано из памяти.
Другое решение проблемы — сконструировать машину, которая не приостанавливает работу, но следит, чтобы программы-компиляторы не использовали слова до того, как они считаны из памяти. Однако это не так просто осуществить на практике. Часто при обработке команды загрузки машина не может выполнять другие действия, поэтому компилятор вынужден вставлять пустые команды, которые не производят никаких операций, но при этом занимают место в памяти. В действительности при таком подходе простаивает не аппаратное, а программное обеспечение, но снижение производительности при этом такое же.