Архивы: по дате | по разделам | по авторам

Наследие века нынешнего

Архив
автор : Сергей Леонов   19.01.1999

1 января 2000 года приходится на воскресенье, выходной перенесут на понедельник: у нас в запасе будет уйма времени - целый уик-энд.
Peter de Jager
(перевод мой. - С.Л.)

"Час X" наступит через 348 дней после выхода в печать этого номера. Время все же категория относительная. С одной стороны, впереди еще целый год, а с другой - всего-навсего 348 дней. С одной стороны, история еще не знала таких глобальных проблем с точно известной датой наступления, решением которых человечество начало бы заниматься столь заблаговременно; с другой - количество строк программного кода, написанного за три десятка лет безудержной компьютеризации общества, превышает все мыслимые цифры. Мало того, неприятных сюрпризов следует ждать не только 1 января будущего года, они могут случиться как раньше, так и позже.


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

   Константа 19 сыграла с нами злую шутку: очередное увеличение года на единицу будет расценено многими творениями рук человеческих как 1999+1=1900. Константа на то и константа. Мало того, ответ 1900 в этом равенстве - не единственный правильный. Отдельные, слишком умные "электронные мозги" резонно заметят, что текущая дата оказалась меньше даты их создания - непорядок, стало быть. И, не придумав ничего лучше, просто переставят текущую дату на дату своего рождения (нам бы так!). А "мозги" безграмотные не заметят ничего и будут спокойно продолжать работу, поздравляя своих создателей, к примеру, с "минусшестидесятилетием": арифметика - наука точная, и ее никто не отменял.

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

   Кроме того, айсберг, видимой частью которого был таймер реального времени компьютера IBM PC AT (см. врезку), оказался несколько больших размеров, чем ожидалось.

 
   Наличием аппаратной "проблемы 2000 года" в компьютерах класса IBM PC мы обязаны двум компаниям - Motorola и IBM. Первой - за то, что ею была создана микросхема аппаратных часов реального времени (RTC - Real-Time Clock) MC146818, не содержащая двух старших разрядов года, а второй - за то, что именно эта микросхема была использована при разработке компьютера IBM PC AT (PC XT и более ранние модели не имели энергонезависимых часов вовсе). В разных вариантах исполнения и под разными названиями (DS1287, КР512ВИ1) эту микросхему или ее модификации производили многие компании. Все эти устройства давным-давно не применяются при разработке новых компьютеров, однако для сохранения программной совместимости архитектура этого таймера полностью повторяется производителями интегрированных чипсетов на протяжении уже почти четверти века. Производители микросхем RTC (а основными на сегодня являются Dallas Semiconductor, Benchmarq Technology, SGS-Thomson и VIA Technologies) выпускают сегодня широчайшую номенклатуру устройств, имеющих полноразрядные счетчики года и коррекцию високосных лет. Однако совместимость - вопрос очень тонкий, и многие производители чипсетов и системных плат предпочитают использовать старую архитектуру, чтобы избежать изменений в BIOS и возможной несовместимости со старым ПО.

   Лишний день
   Если вы считаете, что проблема заключается лишь в двузначном формате представления даты, то ошибаетесь. Это не единственный сюрприз, который подготовил нам новый век. А ведь кроме нового века наступает еще и новое тысячелетие (строго говоря, новый век, как и новое тысячелетие, открывает 2001 год, а вовсе не 2000-й. Но уж больно велика магия круглых чисел!).

   Интересно, кто из вас помнит правило, по которому определяется високосный год? Я до недавнего времени тоже думал, что високосным является год, кратный четырем. Но период обращения Земли вокруг Солнца вовсе не равен периоду собственного обращения нашей планеты, умноженному на 365. Однодневная коррекция раз в четыре года (+1/4 суток) немного превышает требующуюся, поэтому по григорианскому календарю считается, что каждый первый год нового века не является високосным, несмотря на то что записывается кратным четырем числом (-1/100 суток). Но и это еще не все: последняя коррекция также не обеспечивает точного соотношения, и каждый четырехсотый год, несмотря на предыдущее правило, считается все же високосным (+1/400 суток). Итоговое соотношение - 365,2425 дня в году, что тоже не является астрономически точной величиной, ошибка составляет 0,00030122 дня. Однако ею григорианский календарь пренебрегает, так как дополнительная коррекция на полные сутки потребуется только через 33198,8 года.

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

   Проблема определения високосного года, строго говоря, не относится к "часу X" - первому дню нового века, ошибки алгоритмов вычисления високосных лет могут проявиться как 29 февраля 2000 года, так и значительно позже - в 2004-м, 2005-м или даже в 2100 году (будем надеяться, что к тому времени эти ошибки все же исправят). Тем не менее, проблему эту тоже принято относить к Y2K, так как именно переход в 21-й век и не был предусмотрен в ошибочных алгоритмах.

   В качестве маленького лирического отступления расскажу о написанной мною в 16 лет программе для модного в те времена расчета так называемых биоритмов, основанную на вычислении значений трех синусоид с разными периодами, начинающихся со дня рождения человека. Расчет выполнялся на цифровой машине "Мир-1", а написана была программа на "советском АЛГОЛе" под названием "АЛМИР". Никакого формата даты в том языке, помнится, не было (как, впрочем, и часов реального времени в самой ЭВМ, и даже простейшего таймера, про операционную систему я вообще не говорю - для этого класса вычислительных устройств такого понятия просто не существовало), да и не нужно было там абсолютное значение даты. Високосный же год я определял проверкой остатка от деления введенного значения года на четыре: если он равна нулю - значит, год високосный. Сегодня я могу с гордостью сказать, что та программа являлась Y2K-compatible вплоть до 2099 года. Однако корректность ее работы обеспечивалась вовсе не потому, что это было предусмотрено при написании (я тогда и правил григорианского календаря точно не знал, и о каких-то там "проблемах 2000" понятия не было), а потому, что просто повезло, - ошибка алгоритма скомпенсировалась применяемой раз в 400 лет коррекцией, в связи с чем все аналогичные алгоритмы будут правильно определять наличие лишнего дня в году еще на протяжении ста лет.

   Маленькие хитрости
   Сегодня мало кто беспокоится о лишней переменной в программе или лишнем поле в базе данных. Подумаешь, виртуальная память большая, а если и не хватит - это проблемы пользователя, значит, пришла пора апгрейд делать. Однако еще десять лет назад не все было столь очевидно, мегабайт оперативной памяти для персонального компьютера считался роскошью, и программисты старались уложиться в 400-500 Кбайт ОЗУ, чтобы не связываться с нестандартизированными драйверами поддержки extended/expanded/upper-памяти. А если переместиться еще лет на десять назад, когда 4-8 Кбайт ОЗУ занимали объем вдвое больший, чем сегодняшний системный блок, то станет понятно, откуда растут корни следующей проблемы.

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

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

   В качестве примера приведу один безобидный вариант такой экономии. Допустим, нужно хранить массив неких величин, укладывающихся в диапазон от 0 до 100 (проценты, например), с точностью 1. С точки зрения программиста, для хранения каждого значения достаточно 7 бит (и то избыточно), но, при использовании многих стандартных трансляторов, выделить такое поле проблематично, гораздо удобнее поле байтовое. Зная, что величина заведомо не превышает 100, восьмой бит можно использовать для хранения двоичного признака, а при чтении значения, превышающего 100, просто вычитать эту сотню (или 128) и считать признак установленным.

   А вот другой пример, но уже гарантирующий некоторые проблемы. В поле, содержащем дату, до которой необходимо хранить документ, можно добавить пару не предусмотренных значений: "хранить вечно" и "не хранить вообще". В качестве одного из них использовать, к примеру, дату 1.1.00, а в качестве второго - 2.1.00, считая эти даты недействительными, - вот вам и сюрприз к новому веку. Этот абстрактный пример не слишком далек от действительности, хотя я не учел изобретательности программистов. Знаете, какое значение наиболее часто, по оценкам американских экспертов, использовалось в качестве "особого"? Рядовой день 9 сентября теперь уже текущего года. В десятичной записи это 09.09.99 - "все девятки", кто же предполагал, что кусок программного кода, написанный десяток лет назад, доживет до этого "критического дня"?

   Замкнутый круг
   К подобным же проблемам относят и переполнение двоичных счетчиков времени, имеющих фиксированную разрядность и ведущих отсчет не в часах/днях/годах, а в секундах или условных единицах, обычно в периодах срабатывания системного таймера. Подобные счетчики применяются в основном в операционных системах и независимы от аппаратных часов реального времени, часы используются только для начальной установки времени при запуске ОС. Примером могут служить 32-битные ОС SCO Unix, использующие для хранения системного времени 31-разрядный двоичный счетчик секунд, нулевое значение которого соответствует 00:00:00 1 января 1970 года. Нетрудно подсчитать (если в вашем калькуляторе хватит разрядов), что максимальное значение счетчика приходится на 19 января 2038 года, после чего произойдет обнуление, и снова, по мнению ОС, наступит 1970 год. Однако, учитывая планы компании по созданию новых версий ОС, можно рассчитывать, что 32-битная SCO Unix до 2038 года не доживет, будучи заменена 64-битной, которой эта проблема не грозит благодаря увеличению разрядности счетчика.

   Тем же грешат и другие ОС, но дата переполнения везде разная. Так, например, Mac OS может, в отличие от нас с вами, считать время аж до 29940 года.

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

   Частные же проблемы решаются вполне успешно. Недостаток аппаратного таймера компьютеров класса IBM PC может и не вызвать никаких проблем, если BIOS использует полный формат года. В этом случае одна из ячеек энергонезависимой памяти, входящей в состав аппаратных часов, используется для хранения двух старших цифр года (хотя и не связана с самими часами никоим образом) и, соответственно, не увеличивает значение при переходе счетчика года через ноль. Если же BIOS не запрещает использование значений, превышающих 1999, требуется лишь однократная коррекция даты после наступления 2000 года. Все современные версии BIOS выполняют такую коррекцию автоматически (см. врезку), используя следующую процедуру. Как известно, все процедуры BIOS, связанные с датами, вызываются через прерывание 1Ah. В новых версиях в процедуру обработки этого прерывания добавлен код, проверяющий две младшие цифры даты в аппаратных часах, и, в случае если число меньше 80 (1980 год), корректируют значение ячейки энергонезависимой памяти, содержащей две старшие цифры.

 
   Соответствие версий BIOS проблеме 2000 года.
   AMI BIOS
   Все версии AMI BIOS, датируемые 15.07.95 и позже, корректно оперируют датами после 2000 года и автоматически осуществляют переход от 1999-го к 2000 году. Однако из-за того, что множество тайваньских, китайских и американских фирм выпускали системные платы, используя собственные модификации BIOS на основе AMI BIOS, практически неотличимые по заставкам от оригинала, в каждом конкретном случае нужно определить производителя и получить консультацию у него. Помочь в вопросе определения производителя BIOS может сайт компании American Megatrends www.ami.com/support; обновления, правда, имеются только для оригинальных версий BIOS.
   Более ранние версии корректно воспринимают даты после 2000 года, но не выполняют автоматического перехода от 1999-го к 2000 году, то есть требуется однократная коррекция даты вручную.

   Award BIOS
   Версии Award BIOS, выпускавшиеся до 26.04.94, не осуществляют автоматического перехода к 2000 году, однако допускают использование дат от 2000 года и далее, то есть при их использовании требуется однократная ручная коррекция даты.
   Версии, выпущенные в период между 26.04.94 и 31.05.95, не воспринимают даты после 1999 года и требуют переустановки системного времени при каждой перезагрузке. В случае, если OEM-производитель не поставляет исправленную версию, ее можно получить, обратившись непосредственно в компанию Award Software.
   Все версии, выпущенные после 31.05.95, правильно обрабатывают даты и автоматически выполняют переход к 2000 году.
   Следует также отметить, что версии Award BIOS, выпущенные между 31.05.95 и 18.11.96, могут не проходить тест NSTL и некоторые другие. Это, однако, не означает наличия проблем, так как тест использует нетипичный для реального программного обеспечения способ обращения к аппаратным ресурсам (вызов функции 04h прерывания INT1Ah).

   Phoenix BIOS
   Версии Phoenix BIOS 4.0 Release 5 и выше корректно воспринимают даты после 2000 года и автоматически осуществлять переход от 1999-го к 2000 году.
   Более ранние версии корректно воспринимают даты после 2000 года, но не выполняют автоматического перехода к 2000 году, а значит, требуют однократной ручной коррекции даты.

   Существует аналогичное решение и для случая ручного ввода двузначных значений года: в большинстве случаев достаточно считать, что дата относится к следующему столетию, если в качестве года введено значение, меньшее 70 или 80 (в некоторых программах граница может устанавливаться пользователем).

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

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

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

   Тестирование собственно персональных компьютеров можно выполнить и вручную (см. врезку).
 
   Как проверить компьютер без специальных тестовых программ
   Ниже приведена методика выполнения тестов перехода даты (Rollover Test) для различных компонентов вычислительной системы. Не следует, впрочем, считать, что при правильном выполнении всех этих тестов ваш компьютер неуязвим для "проблемы 2000 года". Не забывайте о возможных ошибках в прочем программном обеспечении. Верно также и обратное: непрохождение некоторых тестов вовсе не означает, что компьютер нужно менять. Большинство протестированных мною компьютеров класса PC не проходят, к примеру, тест RTC Rollover, однако это не должно вызывать никаких проблем при корректном прохождении теста BIOS.

   Проверка ОС   
  • Для выполнения теста желательно загрузить операционную систему до монитора командной строки без каких-либо драйверов и резидентных программ, а также отключить компьютер от локальной сети.   
  • С помощью команд date и time (или предназначенных для этого команд вашей ОС) установить системную дату на 31 декабря 1999 года, а время - на 23:59 (для DOS и Windows это команды date 31-12-1999 и time 23:59. Не забывайте, что в нелокализованных версиях формат ввода даты может отличаться от принятого в России).   
  • Проверить правильность установки даты и времени (для DOS и Windows это те же команды без аргументов).   
  • Подождать более одной минуты.   
  • Проверить системную дату еще раз. Если она соответствует 1 января 2000 года, то ваша ОС не имеет "ошибки 2000 года".

       Проверка BIOS   
  • Войти в BIOS Setup (здесь надо отметить, что имеется в виду программа Setup, располагающаяся в ПЗУ BIOS, а не внешняя, запускаемая из операционной системы. Если запущена последняя, то на результат теста может влиять сама ОС).   
  • Установить дату на 31 декабря 1999 года и время на 11:59PM (в большинстве BIOS формат времени и даты соответствует американскому).   
  • Подождать более одной минуты, наблюдая за изменением даты. Если она корректно меняется на 1 января 2000 года, то ваша BIOS не содержит "ошибки 2000 года".

       Проверка аппаратного таймера (RTC)   
  • Войти в BIOS Setup (см. предыдущий тест).   
  • Установить дату на 31 декабря 1999 года и время на 11:59PM (см. предыдущий тест).   
  • Выйти из программы Setup с сохранением установок.   
  • Выключить компьютер.   
  • Подождать более одной минуты, включить компьютер и, не допуская загрузки ОС, войти в BIOS Setup. Если дата установлена на 1 января 2000 года, то аппаратный таймер вашего компьютера не содержит "ошибки 2000 года".   
  • Проверку можно выполнить и для других "опасных" дат.

  • Наиболее критичными и подлежащими обязательному тестированию переходами дат являются следующие:

    08.09.1999 - 09.09.1999,
    09.09.1999 - 10.09.1999,
    31.12.1999 - 01.01.2000,
    28.02.2000 - 29.02.2000,
    29.02.2000 - 01.03.2000.

       Кроме того, в Интернете имеется большое число программ, автоматически выполняющих полный набор тестов. Вот некоторые адреса:
       
  • www.unicore.com/millennium.html,   
  • www.nstl.com/html/nstl_y2k.html,   
  • www.firmware.com,   
  • www.ami.com/amibios/ami_2000.html.

       И не думайте, что раз Нострадамус не упоминал об Y2K, то ничего и не случится, а если и случится, то Билл Гейтс сделает все за вас. Не надейтесь также, что правительство постановит считать 1 января 2000 года первым января 1900 года. Хотя в наше правительство я верю (только пусть тогда не говорят, что это была их идея).

  • © ООО "Компьютерра-Онлайн", 1997-2024
    При цитировании и использовании любых материалов ссылка на "Компьютерру" обязательна.