Практическая работа №4. Деление кривой на равные части. ПП04. Базовая система вводавывода (bios)
Скачать 229.39 Kb.
|
Базовая система ввода-вывода (BIOS) BIOS — это термин, который используется для описания базовой системы ввода-вывода. По существу, BIOS представляет собой “промежуточный слой” между программной и аппаратной частями системы. Большинство пользователей под BIOS подразумевают драйверы устройств. Кроме системной, существует еще BIOS адаптеров, которые загружаются при запуске системы. Итак, базовая система ввода-вывода — это комбинация всех типов BIOS, а также загружаемые драйверы устройств. Часть BIOS, содержащаяся в микросхеме на системной плате или платах адаптеров, называется firmware (именно из-за наличия этих микросхем пользователи чаще всего относят BIOS к аппаратной части компьютера). Стандартная PC-совместимая система состоит из нескольких слоев, которые связаны между собой. На этом рисунке показаны два различных компьютера, в которых используется уникальная BIOS в качестве интерфейса между аппаратным обеспечением и операционной системой и ее приложениями. Таким образом, на этих компьютерах может быть установлено разное оборудование (процессоры, жесткие диски, мониторы и др.), на котором можно запускать одинаковое программное обеспечение. Связь между приложениями и операционной системой осуществляется с помощью соответствующего API (Application Programming Interface). Этот интерфейс определяет, например, как выполняется запись и считывание данных на диск, печать и другие функции. Поскольку приложение не зависит от установленного аппаратного обеспечения, то все его вызовы обрабатывает операционная система, которая уже содержит информацию об установленном оборудовании. Операционная система, в свою очередь, через BIOS обращается непосредственно к аппаратному обеспечению. Эта связь реализована в виде драйверов устройств. Причем в каждой операционной системе — DOS, Windows 9x, Windows NT, Windows 2000, OS/2, Linux или другой — для одного и того же устройства необходимы свои драйверы. Как видно из рис. 4.1, приложения и операционная система идентичны в большинстве компьютеров, а BIOS “подстраивается” под определенное аппаратное обеспечение и, независимо от установленного оборудования, обеспечивает стандартный интерфейс для операционной системы. OS Windows: загрузка, настройка, управление, обслуживание Операционная система – комплекс программ, обеспечивающих взаимодействие всех аппаратных и программных частей компьютера между собой и взаимодействие пользователя и компьютера. Операционная система обеспечивает связь между пользователем, программами и аппаратными устройствами. Структура операционной системы: Ядро – переводит команды с языка программ на язык «машинных кодов», понятный компьютеру. Драйверы – программы, управляющие устройствами. Интерфейс – оболочка, с помощью которой пользователь общается с компьютером. Операционная система обеспечивает совместное функционирование всех устройств компьютера и предоставляет пользователю доступ к его ресурсам. Процесс работы компьютера в определенном смысле сводится к обмену файлами между устройствами. В операционной системе имеются программные модули, управляющие файловой системой. В состав операционной системы входит специальная программа — командный процессор, которая запрашивает у пользователя команды и выполняет их. Пользователь может дать, например, команду выполнения какой-либо операции над файлами (копирование, удаление, переименование), команду вывода документа на печать и т. д. Операционная система должна эти команды выполнить. К магистрали компьютера подключаются различные устройства (дисководы, монитор, клавиатура, мышь, принтер и др.). В состав операционной системы входят драйверы устройств — специальные программы, которые обеспечивают управление работой устройств и согласование информационного обмена с другими устройствами. Любому устройству соответствует свой драйвер. Для упрощения работы пользователя в состав современных операционных систем, и в частности в состав Windows, входят программные модули, создающие графический пользовательский интерфейс. В операционных системах с графическим интерфейсом пользователь может вводить команды посредством мыши, тогда как в режиме командной строки необходимо вводить команды с помощью клавиатуры. Операционная система содержит также сервисные программы, или утилиты. Такие программы позволяют обслуживать диски (проверять, сжимать, дефрагментировать и т. д.), выполнять операции с файлами (архивировать и т. д.), работать в компьютерных сетях и т. д. Для удобства пользователя в операционной системе обычно имеется и справочная система. Она предназначена для оперативного получения необходимой информации о функционировании как операционной системы в целом, так и о работе ее отдельных модулей. Запуск компьютера При поступлении сигнала о запуске процессор обращается к специально выделенной ячейке памяти. В ОЗУ в этот момент ничего нет, если бы там была какая-либо программа, то она начала бы выполнятся. Для того чтобы компьютер мог начать работу необходимо наличие специальной микросхемы – ПЗУ. Программы ПЗУ записываются на заводе и называются BIOS. После включения компьютера процессор начинает считывать и выполнять микрокоманды, которые хранятся в микросхеме BIOS. Прежде всего начинает выполнятся программа тестирования POST, которая проверяет работоспособность основных устройств компьютера. В случае неисправности выдаются определенные звуковые сигналы, а после инициализации видеоадаптера процесс тестирования отображается на экране монитора. Затем BIOS начитает поиск программы-загрузчика операционной системы. Программа-загрузчик помещается в ОЗУ и начинается процесс загрузки файлов операционной системы. Загрузка операционной системы Файлы операционной системы хранятся во внешней, долговременной памяти (на жестком диске, на CD …). Однако программы могут выполнятся, только если они находятся в ОЗУ, поэтому файлы ОС необходимо загрузить в оперативную память. Диск, на котором находятся файлы операционной системы и с которого происходит загрузка, называют системным. Если системные диски в компьютере отсутствуют, на экране монитора появляется сообщение "Non system disk" и компьютер «зависает», т. е. загрузка операционной системы прекращается и компьютер остается неработоспособным. После окончания загрузки операционной системы управление передается командному процессору. В случае использования интерфейса командной строки на экране появляется приглашение системы для ввода команд, в противном случае загружается графический интерфейс операционной системы. В случае загрузки графического интерфейса операционной системы команды могут вводиться с помощью мыши. Элементы интерфейса Windows: Рабочий стол. Название «Рабочий стол» подобрано удачно. На нем, как и на обычном рабочем столе расположены раз-личные программы и инструменты, представленные в виде значков, или иконки. Значки. Значками в Windows обозначаются программы, документы. Запуск производится двойным щелчком кнопки мыши по значку. Программа может быть расположена непосредственно на Рабочем столе, а может быть скрыта глубоко на диске, но и в этом случае представлена на Рабочем столе своим образом – ярлыком. Ярлыки. Ярлык программы – это не сама программа, а только ее образ, указание на то место на диске, где она находится. Двойной щелчок по ярлыку также вызывает запуск программы. Ярлыки от значков отличаются наличием небольшой стрелочки внизу слева. Панель задач. Располагается в нижней части экрана. На ней находятся: кнопка Пуск, кнопки открытых окон, индикаторы и часы. Окно. Окно – один из главных элементов интерфейса Windows. Отладка, тестирование и оптимизация программных модулей На этом этапе производится всесторонняя проверка программ. По поводу того как должно выполняться тестирование, среди разных программистов нет еденного мнения, но они единодушны в том, как тестирование не должно выполняться. Тестирование программы (или ее отдельных модулей) не должен выполнять программист (или группа программистов), создавший эту программу (модуль). Рассмотрим этот этап более подробно. Существуют три аспекта проверки программы на: -правильность; -эффективность реализации; -вычислительную сложность. Проверка правильности (верификация программы) удостоверяет, что программа делает в точности то, для чего она была предназначена. Качественная программа – это программа, выполняющая заранее объявленные действия известным способом и не выполняющая никаких необъявленных действий. Статистика свидетельствует, что стоимость такого тестирования программного продукта составляет не менее 50 процентов стоимости начальной разработки и 70 процентов всей стоимости поддержки программного продукта. Но сколько бы сил и денег не было потрачено на тестирование необходимо понимать, что тесты могут доказать наличие ошибок в программе, но они не могут доказать их отсутствия. Один из общих законов программирования гласит, что ни одна программа не дает желаемых результатов при первой попытке ее трансляции и выполнения. На рисунке изображена диаграмма процентного соотношения причин появления тех или иных ошибок при обработке данных. Из диаграммы видно, что большинство ошибок совершаются именно на этапе кодирования. Существуют два типа программных ошибок: синтаксические и семантические. Синтаксические ошибки возникают из-за нарушений правил (лексики) языка программирования и выявляются во время компиляции. Такие ошибки могут быть исключены сравнительно легко. Большинство из них можно выявить путем простого просмотра текста программы. Чаще всего программисты оставляют этот этап компилятору, однако сквозной просмотр текста иногда бывает полезен. Скорость исправления ошибок, выявленных компилятора зависит от степени знакомства программиста с данным языком. Семантические или логические ошибки приводят к некорректным вычислениям или ошибкам во время выполнения программы (run-time error). Математическая безупречность алгоритма не гарантирует правильности его перевода в программу. Аналогично разумный вид получаемых результатов не дает достаточной гарантии правильности программы. В общем случае нельзя дать общего решения для проведения проверки на правильность программы. Конечно, самым лучшим способом тестирования программы является поставка ее пользователю сразу же после завершения программирования. Единственное слабое место такого метода – этот пользователь больше никогда не купит у вас не одной программы. Выявление и устранение ошибок часто имеет циклический характер. Устранение одной ошибки может породить другую ошибку. Особенно это касается работы с глобальными переменными. Как правило, устранение таких ошибок заключается в разработке и проведении наборов тестов, то есть выполнении программы с тщательно подобранными проверочными данными для которых известен правильный ответ. При подготовке к тестированию следует придерживаться следующих правил: 1.Чем раньше спроектирован тест, тем вероятнее выявление ошибок. Поэтому лучше готовить тесты еще на этапе проектирования системы. 2.Недопустима хаотичность процесса тестирования. Он должен быть документирован и полностью управляем. 3.Необходимы повторяемость и завершенность тестов. 4.Следует избегать добавления новых тестов в процессе тестирования. Первым шагом семантической проверки является ручной прогон, то есть программист моделирует прохождение данных через его программу с помощью карандаша и листа бумаги. Это скучная и утомительная работа, однако большинство ошибок может быть выявлено именно на этой стадии. Разумеется, таким образом нельзя проверить всевозможные комбинации данных. Однако можно проверить всевозможные типы или наиболее вероятные комбинации данных. Если они дают правильные результаты, предполагается, что непроверенные комбинации также дали бы правильные результаты. Отдельно тестируется каждый модуль программы. Если программа хорошо спроектирована, то после этого остается проверить только интерфейс между модулями. Следует особо подчеркнуть, что первоначальное тестирование процедур модуля выполняется программистом путем написание коротких «программок», которые вызывают процедуры в различными наборами параметров. Начинающему программисту такой подход может показаться очень расточительным с точки зрения расходования рабочего времени, но это единственный способ более или менее эффективной борьбы с ошибками в программе. Очень часто тесты (файлы с тестовыми данными) создаются вручную. Следовательно, их число редко превышает два-три десятка. Иногда применяют генераторы тестовых данных – специальные программы, формирующие данные в соответствии со спецификациями задаваемыми программистами. Данные могут группироваться в записи, имеющие установленные форматы. Тестовые данные могут также систематически или случайно выбираться из другого заданного набора данных для уменьшения их общего количества, над которыми выполняется тест. Кроме того, необходимо на завершающем этапе тестирования следует прогнать программу на реальном объеме данных и посмотреть насколько интерфейс программы выдержит такую нагрузку. (Очень часто программа прекрасно работающая для двух десятков записей в базе данных через год, когда база будет насчитывать сотни тысяч записей, будет выполняться несколько минут). Если прогон программы на тестовых данных дает неверный результат, то необходимо найти и исправить ошибку. При отладке программыиспользуют три основных способа: -распечатка текущего состояния -точка останова -трассировка Распечатка текущего состояния используется с целью фиксации фактических значений переменных для проверки хода вычислений. Для этого во время отладки программы в местах, которые программист считает критическими, помещают функции вывода на экран текущего состояния переменных. После окончания теста вызовы этих функций удаляются и программа снова перекомпилируется. Метод «точки останова» обычно применяют при разного рода зацикливаниях. В текст программы включают функции останова программы, например можно вывести на экран сообщение «Достигнута точка n» и вызвать функцию getch(). Этот метод имеет смысл объединять с методом деления пополам. Точка останова ставится в средине программы, если программа выполнилась до этой точки, что точка останова ставиться в средине второй половины программы, если нет, то в средине первой и т.д. Таким образом область поиска ошибки постепенно сужается. Трассировка – это пошаговое выполнение программы с возможностью просматривать состояние всех переменных. Она может оказаться очень эффективной, но значительно замедляет выполнение программы и не будучи тщательно спланированной, приводит к колоссальным объемам выдаваемой информации. Проверка вычислительной сложности, как правило, заключается в экспериментальном анализе сложности алгоритма или экспериментальном сравнении двух алгоритмов и более, решающих одну и ту же задачу. (Будет подробнее рассмотрена в последующих темах курса) Проверка эффективности реализации (оптимизация) направлена на отыскание способа заставить правильную программу работать быстрее или расходовать меньше памяти. Теоретически, оптимизация не является обязательным условием разработки программы. Множество программ может быть поставлено (и поставляется) сразу же после отладки. Однако существует целый ряд программ, критичных как к скорости выполнения, так и к размеру. К таким программам относятся, например, программы графического вывода в силу большого объема вычислений, связанных с графическими преобразованиями. Очевидно, что оптимизация должна проводиться опытными программистами, хорошо знакомыми с тонкостями языка и компилятора. Поэтому сегодня чаще оптимизируются только фрагменты программы, влияющие на скорость вывода на экран изображений. При проектировании больших систем оптимизацию производится в два этапа. Сначала оптимизируется текст программы на языке высокого уровня, а затем наиболее критичные ко времени выполнения процедуры переписывают на языке ассемблера. Чтобы улучшить программу, пересматриваются результаты реализации в процессе построения алгоритма. Не рассматривая все возможные варианты и направления оптимизации программ, приведем здесь некоторые полезные способы, направленные на увеличение скорости выполнения программ. Первый способ основан на следующем правиле. Сложение и вычитание выполняются быстрее, чем умножение и деление.Целочисленная арифметика быстрее арифметики вещественных чисел. Таким образом, X+X лучше, чем 2*X, а (2i+j)*0,5 хуже, чем (i+i+j)*0,5. Умножение выолняется быстрее чем деление, например sum*=0,5 лучше чем sum/=2;При выполнении операций над целыми числами следует помнить, что благодаря применению двоичной системы счисления умножение числа, кратные двум, можно заменить соответствующим количеством сдвигов влево. Поэтому 10*А выполняется дольше, чем (A Второй способ заключается вудалении избыточных вычислений. Пример, вычисление квадратных корней уровнения root1=(-b+sqrt(b*b-4*a*c))/(2*a); root2=(-b+sqrt(b*b-4*a*c))/(2*a); Лучшим решением является следующее denomA=a+a; denomC=c+c; diskrim=sqtr(b*b-denomA*demonС); root1=(-b+diskrim)/demomA; root2=(-b-diskrim)/demomA; Легко увидеть, что в первом случае потребовалось выполнить четыре операции сложения/вычитания, восемь операций умножения, две операции деления, два вызова функции sqrt, во втором — пять операций сложения/вычитания, два умножения, два деления и одно обращение к функции sqrt. Третий способ проверки эффективности реализации основан на способности некоторых компиляторов строить коды для вычисления логических выражений так, что вычисления прекращаются, если результат становится очевидным. Например, в выражении A||B||C, если A имеет значение «истина», то переменные В и С уже не проверяются. Таким образом, можно сэкономить время, разместив переменные A,B,С так, чтобы первой стояла переменная, которая вероятнее всего будет истинной, а последней та, которая реже всего принимает истинное значение. Однако следует быть осторожным в следующем примере: ROOL(A)||B||C. ROOL(A) может и чаще принимает значение «истина», но представляет собой вызов функции, возможно выполняющей сложные и длительные вычисления. Тогда может оказаться, что запись В||С||ROOL(A) является более эффективной. Четвертый прием — исключение циклов. Пример. Рассмотрим следующий пример: сформировать одномерный массив, каждый элемент которого должен быть равен сумме элементов строки двумерного массива. for (i=0;i for (i=0;i for (j=0;j можно переписать так for (i=0;i { b=c[i][0]; for (j=1;j b+=c[i][j]; a[i]=b; } В данном пример выигрыш достигается, во-первых, за счет уменьшения количества циклов (два, а не три), а во-вторых, за счет того, что с введением временной переменной b уменьшено количество операций вычисления адресов элементов массива. Пятый прием – развертывание циклов. Пример. Следующий фрагмент for(i=0; i for(j=0; j a[i]+=c[i][j]; можно переписать так: for(i=0; i a[i]+=c[i][0]+c[i][1]+c[i][2]; Выигрыш в скорости вычислений вполне очевиден. Шестой прием – разгрузка участков повторяемости, то есть вынос из циклов выражений, которые могут быть вычислены вне циклов. Например, for (int i=0; i { if (P==S) y=1; else y=S+25; x[i]=(y+i)/2; } лучше переписать if (P==S) y=1; else y=S+25; for (int i=0; i x[i]=(y+i)/2; В данном случае используется так называемая чистка цикла вверх.Однако в следующем примере таким образом нельзя разгрузить цикл: for (int i=0; i { x*=i; if (z0) c=chr(x); else a=x+2; } Действительно, при вычислении значений переменных с и a используется переменная x, значение которой вычисляется в цикле. Однако, значение переменных все равно определяется значением переменной x, вычисленной на последней итерации цикла. Поэтому эффективнее переписать данный фрагмент следующим образом, применяя чистку цикла вниз: for (int i=0; i if (z0) c=chr(x); else a=x+2; Кроме указанных способов оптимизации полезно производить чистку программы, то есть удаление из нее ненужных объектов и конструкций: -удаление идентичных операторов; -удаление несущественных операторов, то есть операторов не влияющих на результат программы; -удаление бесполезных операторов, вычисляющих вспомогательные переменные, используемые только для постановки в другие выражения; -удаление функций, к которым нет обращений; -удаление объявленных, но неиспользуемых переменных, операций и т.д. Также существует ряд способов экономного расходования памяти: -совмещение по памяти не существующих одновременно статических переменных, то есть несвязанные переменные следует объявлять в различных модулях, а не в теле главной программы. -изменение времени жизни переменной -перемещение оператора объявление переменной ближе к фрагменту, где переменная используется -экономия стека: при передаче массива в качестве параметра подпрограммы, следует использовать указатель на массив. Кроме того, следует делать текст программы более компактным (если это не приводит к ухудшению читабельности). Необходимо следить за дублированием в различных ветвях алгоритмов, и сокращать текст программы за счет оформления повторяющихся фрагментов текста в виде функций. Однако не следует слишком злоупотреблять созданием процедур: наличие большого количества процедур, состоящих из 2-3 операторов, вряд ли можно считать приемлемым. Это далеко не полный перечень способов оптимизации. Здесь приведены лишь самые очевидные из них. Следует, кроме того, заметить, что не всегда стоит увлекаться погоней за быстродействием, так как при этом чаще ухудшается удобочитаемость программы. Внедрение и сопровождение Внедрение – это процесс запуска программы в промышленную эксплуатацию. Этот этап характерен для программ, разрабатываемых на заказ. При внедрении разработчик устанавливает продукт на компьютеры заказчика (инсталлирует его) и проверяет весь его рабочий цикл. Это этап эксплуатации системы. Если программа работает устойчиво, начинается этап обучения пользователей. (В договоре необходимо заранее указать объем учебных часов, которые разработчики должны посвятить обучению заказчика.) Сопровождение – это процесс поддержки внедренной программы. Сопровождение предусматривает оказание консультаций, а также внесение необходимых изменений в программу. Каким бы изощренным ни было тестирование программ, к сожалению, в больших программных комплексах чрезвычайно тяжело устранить абсолютно все ошибки. Устранение обнаруженных при сопровождении — задача этого этапа. По мере выявления и исправления ошибок в ходе сопровождения их количество постепенно уменьшается. Однако через какое-то время кривая ошибок вновь начинает расти. Можно предположить, что происходить нечто вроде интерференции волн различной частоты – два процесса накладываются друг на друга, приводя систему к краху. Первый процесс – порождение новых ошибок при исправлении предыдущих, второй – повышение квалификации пользователей при работе с программой и как следствие использование ими тех возможностей программы, которые они раньше не использовали. Выполняемый в ходе сопровождения анализ опыта эксплуатации программы позволяет обнаруживать узкие местам или неудачные проектные решения в тех или иных частях программного комплекса. В результате такого анализа может быть принято решение о проведении работ по совершенствованию разработанной системы. Кроме описанного выше сопровождение может включать в себя проведение консультаций, обучение пользователей системы, оперативное снабжение пользователей информацией о новых версиях системы и т.п. Качественное проведение этапа сопровождения в большой степени определяет коммерческий успех программного продукта. Все исправления, вносимые на этапе сопровождения приводят к изменю структуры программы в сторону ее ухудшения и в конечном счете к дезорганизации системы. В конце концов, наступает момент, когда дальнейшее исправление ошибок в программе теряет всякий смысл. С этого момента, можно считать, что программа умерла. На самом деле, незначительное число программ доживают до собственной «смерти». Чаще программа заменяется на новую или новую версию данной. Новая версия программы обычно учитывает ошибки предыдущей, а также дополнительные требования, возникшие в связи с появлением новой техники и более глубоким осмыслением задачи пользователем. Задачи в условиях неопределенности Эти задачи имеют место тогда, когда информация, необходимая для принятия решений, является неточной, неполной, неколичественной, а формальные модели исследуемой системы либо слишком сложны, либо отсутствуют. В таких случаях для решения задачи обычно привлекаются знания экспертов. В отличие от подхода, принятого в экспертных системах, для решения ЗПР знания экспертов обычно выражены в виде некоторых количественных данных, называемых предпочтениями. Организация защиты данных в хранилищах |