Предисловие 25 января 2009 г. Институту системного программирования РАН исполняется 15 лет. Все эти годы основными задачами Института являлись фундаментальные исследования в области системного программирования, прикладные исследования и разработки в интересах различных областей индустрии и образование. Во всех этих областях удалось добиться значительных успехов. Результаты исследований и разработок освещаются на страницах web-сайта Института, публикуются в регулярных и тематических выпусках Трудов Института системного программирования РАН, ведущем российском журнале «Программирование», авторитетных зарубежных изданиях, докладываются на авторитетных российских и международных конференциях. Проекты, выполняемые специалистами Института, поддерживаются грантами РФФИ, Министерства образования и науки, Президиума РАН и Отделения математики. Прикладные исследования и разработки выполняются на основе контрактов с российскими и зарубежными компаниями. Сотрудники Института активно занимаются преподавательской деятельностью на кафедрах системного программирования факультетов Вычислительной математики и кибернетики МГУ им. М.В. Ломоносова и Управления и прикладной математики Московского физико-технического института. Многие студенты этих кафедр одновременно с базовым обучением активно участвуют в исследовательской работе отделов Института, после получения дипломов поступают в аспирантуру своих университетов и остаются работать в ИСП РАН. В результате в ИСП РАН работает очень много талантливых молодых исследователей и разработчиков, квалификация которых позволяет им активно участвовать в проектах Института, а зачастую и руководить ими. Это является залогом того, что и в будущем ИСП РАН сможет плодотворно решать актуальные и сложные проблемы системного программирования. Настоящий юбилейный сборник Трудов института системного программирования РАН полностью состоит из статей, написанных молодыми сотрудниками ИСП РАН и посвященных результатам выполняемых ими исследовательских проектов. В статье А. Аветисяна, В. Бабковой и А. Монакова «Обеспечение высокопродуктивного программирования для современных параллельных платформ» описываются перспективные направления исследований по высокопродуктивному программированию для параллельных систем с распределенной памятью. Обсуждаются текущие исследования и направления будущих работ, связанных с эффективным программированием многоядерных и гетерогенных систем. 5
Статья А. Белеванцева, Д. Журихина и Д. Мельника «Компиляция программ для современных архитектур» содержит обзор работ по оптимизации программ для современных вычислительных архитектур, проводимых в отделе компиляторных технологий ИСП РАН. Работы включают в себя выявление параллелизма на уровне команд для архитектуры Intel Itanium, исследование и разработку энергосберегающих оптимизаций для архитектуры ARM, а также исследования по динамическим оптимизациям для языков общего назначения, выполняемым на машине пользователя. Большая часть этих работ выполнялось на основе компилятора GCC с открытыми исходными кодами, являющегося стандартным компилятором для Unix-подобных систем. В статье В. Падаряна, А. Гетьмана и М. Соловьева «Программная среда для динамического анализа бинарного кода» рассматривается среда TrEx, позволяющая выполнять динамический анализ защищенного бинарного кода. Преследуемой целью является получение описания интересующего алгоритма. В среде TrEx реализуется оригинальная методика анализа и обеспечивается развитый набор программных средств, объединенных в рамках единого графического интерфейса. Подробно рассматриваются некоторые особенности среды, такие как аритектурнонезависимое API для работы средств анализа, возможности свертки вызовов функций, расширение пользовательского интерфейса скриптовым языком. В статье В. Кулямина «Перспективы интеграции методов верификации программного обеспечения» предлагается подход к построению расширяемой среды верификации программных систем, которая, по мнению автора, поможет решить проблемы практической применимости современных строгих методов верификации к практически значимым программам, сложность которых все время растет. Она же может стать аналогом испытательного стенда для апробации и отладки большого числа новых предлагаемых методов формальных верификации и статического анализа на разнообразном производственном программном обеспечении. В статье В. Мутилина «Метод проверки линеаризуемости многопоточных Java программ» описывается новый метод Sapsan, предназначаемый для функционального тестирования Java-программ с программным интерфейсом (API), процедуры (операции) которого можно вызывать из нескольких потоков одновременно. Метод Sapsan позволяет проверять одно из распространенных требований к таким программам – требование линеаризуемости, заключающееся в том, что параллельное выполнение операций эквивалентно некоторому последовательному выполнению этих же операций, удовлетворяющему спецификации. Статья А. Камкина «Метод формальной спецификации аппаратуры с конвейерной организацией и его приложение к задачам функционального тестирования» посвящена обсуждению метода формальной спецификации аппаратуры с конвейерной организацией, основанного на пред- и постусловиях стадий выполнения операций. Данный метод может быть 6
использован для функционального тестирования моделей аппаратуры, поскольку на основе спецификаций предлагаемого вида можно решать основные задачи тестирования: проверку правильности поведения системы и генерацию тестовой последовательности. Метод был успешно применен для тестирования нескольких модулей промышленного микропроцессора. В результате тестирования были найдены критичные ошибки, не обнаруженные при использовании других подходов. В статье В. Рубанова «Современная инфраструктура для обеспечения совместимости Linux-платформ и приложений» описывается подход к построению инфраструктуры для эффективной разработки и использования спецификаций Linux-платформ. Подобные спецификации описывают программные интерфейсы (API) для обеспечения совместимости между различными реализациями таких платформ и различными приложениями для них. Задача рассматривается в условиях эволюционирующих версий спецификации платформы и наличия множественных платформенных реализаций и приложений, удовлетворяющих той или иной версии спецификации. Предлагаемый подход основан на использовании централизованной базы данных, содержащей структурированную информацию о различных версиях спецификации и различных реализациях платформ и приложений, а также средств автоматической верификации фактического соответствия реализаций платформ и приложений той или иной версии спецификации. Подход иллюстрируется на примере инфраструктуры для поддержки стандарта Linux Standard Base (LSB), основного промышленного стандарта на интерфейсы базовых библиотек операционной системы Linux. В статье М. Гринева и И. Щеклеина «Ориентированные на приложения методы хранения XML-данных» утверждается, что единственно возможным подходом, способным обеспечить высокую эффективность управления XMLданными на основе универсальной модели данных XQury, является выбор способов внутреннего представления и методов обработки данных под потребности конкретного приложения. Достаточной информацией для описания потребностей является схема XML-данных и рабочая нагрузка в виде возможных запросов и операций модификации данных. Предлагается выбирать структуры хранения данных, необходимые для эффективного выполнения запросов и модификаций для данного приложения. Такой подход позволит поддерживать модель данных XQuery на логическом уровне, но избежать излишних накладных расходов на физическом уровне хранения данных. Описываются первые результаты по разработке таких методов хранения и обработки XML-данных. Наконец, в статье М. Гриневой и М. Гринева «Анализ текстовых документов для извлечения тематически сгруппированных ключевых терминов» предлагается новый метод извлечения ключевых терминов из текстовых документов. В качестве важной особенности метода отмечается тот факт, что 7
результатом его метода являются группы ключевых терминов, и термины из каждой группы семантически связаны с одной из основных тем документа. Метод основан на комбинации следующих двух техник: мера семантической близости терминов, посчитанная с использованием Википедии; алгоритм для обнаружения сообществ в сетях. Одним из преимуществ метода является отсутствие необходимости в предварительном обучении, поскольку метод работает с базой знаний Википедии. Экспериментальная оценка метода показала, что метод позволяет извлекать ключевые термины с высокой точностью и полнотой. Академик РАН В.П. Иванников
8
Обеспечение высокопродуктивного программирования для современных параллельных платформ А.И. Аветисян, В.В. Бабкова, А.В. Монаков {arut, barbara, amonakov}@ispras.ru http://www.ispras.ru/groups/ctt/parjava.html Аннотация. В настоящей статье описываются некоторые перспективные направления исследований по высокопродуктивному программированию для параллельных систем с распределенной памятью, проводимые в отделе компиляторных технологий Института системного программирования РАН. Обсуждаются текущие исследования и направления будущих работ, связанных с высокопродуктивным программированием многоядерных и гетерогенных систем.
1. Введение Развитие компьютерных и сетевых технологий привело к тому, что одним из основных свойств современных вычислительных систем является параллелизм на всех уровнях. Происходит широкое внедрение кластерных систем (распределенная память) с тысячами процессоров. Началось широкое производство многоядерных процессоров общего назначения, Современные многоядерные процессоры имеют не более 16 ядер, однако производители уже серьезно говорят о нескольких сотнях и даже тысячах ядер [1]. Кроме того, выпускаются специализированные процессоры, содержащие сотни параллельно работающих ядер на одном чипе (графические акселераторы компаний AMD и nVidia). Высокая производительность, низкое энергопотребление и низкая стоимость специализированных многоядерных процессоров (как правило, это процессоры для компьютерных игр) способствовали стремлению использовать их не только по их прямому назначению. Начались исследования возможностей широкого применения гетерогенных архитектур, состоящих из процессора общего назначения и набора специализированных многоядерных процессоров (акселераторов) для решения вычислительных задач общего назначения. Акселератор имеет доступ как к своей собственной памяти, так и к общей памяти гетерогенной системы. Примерами таких архитектур являются: архитектура IBM Cell, архитектуры, использующие графические акселераторы компаний AMD и nVidia, многоядерный графический ускоритель Larrabee компании Intel. 9
Остро встал вопрос о языках параллельного программирования, которые могли бы обеспечить достаточно высокую производительность труда программистов, разрабатывающих параллельные приложения. Однако языки, разработанные в 90-е годы (HPF [2], UPC [3] и др.) не смогли решить эту проблему [4]. Это привело к тому, что промышленную разработку прикладных параллельных программ, обеспечивающих необходимое качество, приходится вести, на так называемом «ассемблерном» уровне, на последовательных языках программирования (C/C++, Fortran), разработанных в 60-70 гг., с явным использованием обращений к коммуникационной библиотеке MPI (для систем с распределенной памятью), явным указанием прагм OpenMP (для систем с общей памятью), с использованием технологии программирования CUDA [5] (расширение языка C для акселераторов Nvidia), которая точно отражает организацию оборудования, что позволяет создавать эффективные программы, но требует высокого уровня понимания архитектуры акселератора и др. Таким образом, в настоящее время параллельное программирование связано с ручной доводкой программ (распределение данных, шаблоны коммуникаций, либо синхронизации доступа к критическим данным и т.п.). Это связано со значительными затратами ресурсов и требует высокой квалификации прикладных программистов. Цена, которую нужно заплатить, чтобы добиться хорошей производительности и требуемой степени масштабируемости приложений, часто оказывается непомерно высокой. Поэтому целью современных исследований является фундаментальная проблема высокой продуктивности [6] разработки параллельных приложений, когда обеспечивается достаточный уровень производительности при приемлемом уровне затрат на разработку. Это особенно актуально в связи с тем, что параллельное программирование становиться массовым. Исследования ведутся по многим направлениям: изучаются свойства приложений, делаются попытки классификации приложений, в том числе для выявления в них общих ядер; исследуются свойства аппаратуры с целью максимального их использования и развития; ведутся исследования и разработки по целому спектру средств программирования. Одним из направлений исследований является разработка языков нового поколения (X10 [7], Chapel [8], Fortress [9], Cilk [10], Brook+ [11] и др.). Несмотря на то, что эти разработки опираются на опыт предыдущих лет, пока они не привели к успеху, прежде всего, из-за недостаточного уровня современных компиляторных технологий. Реализуются как промышленные, так и исследовательские, системы, поддерживающие доводку программ разрабатываемых на «ассемблерном» уровне. К настоящему времени известно несколько таких систем: отладчики DDT [12], TotalView [13], система TAU [14], разработанная в университете штата Орегон и др. 10
Одним из таких средств является интегрированная среда ParJava [15], разработанная в ИСП РАН, которая предоставляет прикладному программисту набор инструментальных средств, поддерживающих разработку параллельных программ для вычислительных систем с распределенной памятью (высокопроизводительных кластеров) на языке Java, расширенном стандартной библиотекой передачи сообщений MPI. В настоящее время среда Java представляет значительный интерес с точки зрения высокопроизводительных вычислений. Это связано как с положительными свойствами Java как среды разработки прикладных программ (переносимость, простота отладки и др.), так и с тем, что использование инфраструктуры Java существенно упрощает разработку инструментальных средств. Можно упомянуть такие системы как: ProActive Parallel Suite [16] (INRIA), MPJ Express [17] (University of Reading and University of Southampton), Distributed Parallel Programming Environment for Java [18] (IBM) и др. Кроме того, добавлена поддержка Java + MPI в известной среде разработки параллельных программ на языках C/C++ и Fortran 77/90 TAU. В проекте ParJava решались две задачи: обеспечить возможность эффективного выполнения параллельных программ на языке Java с явными обращениями к MPI на высокопроизводительных кластерных системах и разработать технологический процесс реализации параллельных программ, обеспечивающий возможность переноса как можно большей части разработки на инструментальный компьютер. В настоящей статье описываются некоторые перспективные направления исследований по высокопродуктивному программированию для параллельных систем с распределенной памятью, проводимые в отделе компиляторных технологий Института системного программирования РАН. Обсуждаются текущие исследования и направления будущих работ, связанных с высокопродуктивным программированием многоядерных и гетерогенных систем. Статья состоит из 4 разделов. В разделе 2 описывается среда ParJava, модель параллельной Java-программы и возможности ее интерпретации, технологический процесс разработки программ в среде ParJava, механизмы времени выполнения. В разделе 3 приводятся результаты применения среды при разработке программ моделирования интенсивных атмосферных вихрей (ИАВ) и моделирования теплового движения молекул воды и ионов в присутствии фрагмента ДНК. В разделе 4 обсуждаются направления дальнейших исследований.
2. Средства разработки параллельных приложений в среде Java Среда ParJava позволяет выполнять большую часть разработки параллельной Java-программы на инструментальном компьютере. Для этого используется модель параллельной Java-программы [19], интерпретируя которую на 11
инструментальном компьютере можно получить оценки времени выполнения программы на заданном кластере (кластер определяется числом узлов, параметрами платформы, используемой в качестве его узлов, и параметрами его коммуникационной сети), а также оценки других динамических атрибутов программы, построить модели ее профилей и трасс. Полученная информация о динамических свойствах параллельной программы позволяет оценить границы ее области масштабируемости, помогает прикладному программисту вручную оптимизировать программу, проверяя на интерпретаторе, как отразились произведенные изменения на ее масштабируемости. Возможность использования инструментального компьютера для оптимизации и доводки параллельной программы избавляет программиста от большей части отладочных запусков программы на целевой вычислительной системе, сокращая период отладки и доводки программы.
2.1. Модель параллельной интерпретация
Java-программы
и
ее
Модель SPMD-программы представляет собой совокупность моделей всех классов, входящих в состав моделируемой программы. Модель каждого класса – это множество моделей всех методов этого класса; кроме того, в модель класса включается модель еще одного дополнительного метода, описывающего поля класса, его статические переменные, а также инициализацию полей и статических переменных. Модель метода (функции) состоит из списка описаний локальных и глобальных переменных метода и модифицированного абстрактного синтаксического дерева метода: внутренние вершины модели соответствуют операторам языка Java, а листовые – базовым блокам. В качестве базовых блоков рассматриваются не только линейные последовательности вычислений (вычислительные базовые блоки), но также и вызовы библиотечных функций, вызовы пользовательских методов и функций и вызовы коммуникационных функций. Для обеспечения возможности интерпретации модели по частям введено понятие редуцированного блока, который представляет значения динамических атрибутов уже проинтерпретированных частей метода. Каждый MPI-процесс моделируемой программы представляется в ее модели с помощью логического процесса, который определен как последовательность действий (примеры действий: выполнение базового блока, выполнение операции обмена и т.п.). Каждое действие имеет определенную продолжительность. В логическом процессе определено понятие модельных часов. Начальное показание модельных часов каждого логического процесса равно нулю. После интерпретации очередного действия к модельным часам соответствующего логического процесса добавляется значение времени, затраченного на выполнение этого действия (продолжительности). Продолжительность каждого действия, а также значения исследуемых динамических параметров базовых блоков, измеряются заранее на целевой платформе. 12
Для идентификации логических процессов используются номера моделируемых процессов, использованные в моделируемой программе при описании коммуникатора MPI (будем называть их пользовательскими номерами процессов). Как известно, для удобства программирования приложений в стандарте MPI реализована возможность задавать коммуникаторы, позволяющие задавать виртуальные топологии сети процессоров, описывая группы процессов. В среде ParJava коммуникаторы, заданные программистом, отображаются на MPI_COMM_WORLD, получая, тем самым, наряду с пользовательскими номерами внутренние номера. Все инструменты среды ParJava работают с внутренними номерами процессов, но при выдаче сообщений пользователю эти номера переводятся в пользовательские. В дальнейшем, при упоминании номера логического процесса будет подразумеваться его внутренний (системный) номер. Внутренний номер используется для доступа к логическому процессу при моделировании коммуникационных функций. Для сокращения времени интерпретации и обеспечения возможности выполнения интерпретации на инструментальном компьютере в среде ParJava моделируются только потоки управления процессов моделируемой программы и операции обмена данными между процессами. Это допустимо, так как значения времени выполнения и других исследуемых динамических атрибутов базовых блоков определяются на целевой вычислительной системе до начала интерпретации модели. Интерпретация модели лишь распространяет значения указанных динамических атрибутов на остальные узлы модели. Такой подход позволяет исключить из моделей базовых блоков переменные, значения которых не влияют на поток управления моделируемой программы. В результате часть вычислений, в которых определяются и используются указанные переменные, становится «мертвым кодом» и тоже исключается, что ведет к сокращению, как объема обрабатываемых данных, так и общего объема вычислений во время интерпретации. В некоторых базовых блоках описанный процесс может привести к исключению всех вычислений, такие базовые блоки заменяются редуцированными блоками. Внутреннее представление модели SPMD-программы разрабатывалось таким образом, чтобы обеспечить возможность возложить как можно большую часть функций интерпретатора на JavaVM. Такое решение позволило существенно упростить реализацию интерпретатора и обеспечить достаточно высокую скорость интерпретации, однако для его реализации потребовалось внести некоторые структурные изменения в модель параллельной программы. Внутреннее представление модели базового блока B представляет собой пару 〈DescrB, BodyB〉, где DescrB – дескриптор блока B (т.е. семерка 〈id, τ, P, IC, OC, Time, A〉, где id – уникальный идентификатор базового блока, присваиваемый ему при построении модели, τ – тип базового блока, P – ссылка на модель его тела, IC – множество входных управляющих переменных, OC – множество выходных управляющих переменных, Time – время выполнения базового 13
блока, A – ссылка на список остальных его атрибутов), а BodyB – модель тела блока B (список выражений на байт-коде, вычисляемых в блоке B). Внутреннее представление модели метода определяется как тройка 〈дескриптор метода, модель потока управления, модель вычислений〉. Дескриптор метода содержит сигнатуру метода, список генерируемых методом исключений, список дескрипторов формальных параметров и ссылки на модель потока управления и модель вычислений. Модель потока управления – это модифицированное АСД, описанное в [19], в котором базовые блоки представлены своими дескрипторами. Модель вычислений – это преобразованный байт-код интерпретируемой Java-программы: все базовые блоки модели вычислений включены в состав переключателя, значение управляющей переменной которого определяет номер очередного интерпретируемого базового блока. Интерпретация модели состоит в выполнении Java-программы, определяющей модель вычислений на JavaVM: в интерпретаторе модели потока управления определяется очередное значение управляющей переменной переключателя модели вычислений, после чего интерпретируется модель соответствующего базового блока. Интерпретация модели базового блока определяется его типом. Для блоков типа «вычислительный блок» (время выполнения таких базовых блоков определяется заранее на целевой платформе) вносится соответствующее изменение во временной профиль метода, и управление возвращается в модель вычислений. Для блоков типа «вызов пользовательской функции», управление возвращается в модель вычислений, где вызывается модель вычислений этого метода. Во время выполнения вызванной модели вычислений в стек помещается текущее состояние, и подгружаются необходимые структуры данных. После интерпретации метода из стека извлекается состояние на момент вызова пользовательской функции и продолжается выполнение модели вычислений первой функции. Для блоков типа «вызов коммуникационной функции», управление возвращается в модель вычислений, где вызывается модель соответствующей коммуникационной функции, которая помимо выполнения передачи данных между логическими процессами обеспечивает вычисление оценки времени выполнения коммуникации и внесение соответствующих изменений во временной профиль. При интерпретации блоков типа «редуцированный блок» (динамические атрибуты таких блоков уже определены и они не интерпретируются), возврат в модель вычислений не происходит; вносятся изменения во временной профиль, и выполняется поиск следующего базового блока.
2.2. Технологический процесс программ в среде ParJava
разработки
параллельных
В рамках среды ParJava разработан и реализован ряд инструментальных средств, которые интегрированы с открытой средой разработки Java-программ Eclipse [20]. После подключения этих инструментальных средств к Eclipse, 14
получилась единая среда разработки SPMD-программ, включающая как инструменты среды ParJava, так и инструменты среды Eclipse: текстовый редактор, возможность создания и ведения проектов, возможность инкрементальной трансляции исходной программы во внутреннее представление. Интеграция в среду Eclipse осуществлена с помощью механизма «подключаемых модулей». При разработке параллельной программы по последовательной программе сначала оценивается доля последовательных вычислений, что позволяет (с помощью инструмента “Speed-up”) получить оценку максимального потенциально достижимого ускорения в предположении, что все циклы, отмеченные прикладным программистом, могут быть распараллелены. Затем с использованием инструмента “Loop Analyzer” среды ParJava циклы исследуются на возможность их распараллелить. Для распараллеленных циклов с помощью инструмента “DataDistr” подбирается оптимальное распределение данных по узлам вычислительной сети. В частности, для гнезд циклов, в которых все индексные выражения и все границы циклов заданы аффинными формами, инструмент “DataDistr” позволяет с помощью алгоритма [21] найти такое распределение итераций циклов по процессорам, при котором не требуется синхронизаций (обменов данными), если, конечно, требуемое распределение существует (см. ниже пример 1). В этом случае инструмент “DataDistr” выясняет, можно ли так распределить итерации цикла по узлам, чтобы любые два обращения к одному и тому же элементу массива попали на один и тот же процессор. Для этого методом ветвей и сечений находится решение задачи целочисленного линейного программирования, в которую входят ограничения на переменные циклов, связанные с необходимостью оставаться внутри границ циклов, и условия попадания на один и тот же процессор для всех пар обращений к одинаковым элементам массива. Задача решается относительно номеров процессоров, причем для удобства процессоры нумеруются с помощью аффинных форм (т.е. рассматривается многомерный массив процессоров). Если оказывается, что для обеспечения сформулированных условий все данные должны попасть на один процессор, это означает, что цикл не может выполняться параллельно без синхронизации. В последнем случае инструмент “DataDistr” может в диалоговом режиме найти распределение данных по узлам, требующее минимального числа синхронизаций при обменах данными. Для этого к условиям сформулированной задачи линейного программирования добавляются условия на время обращений к одним и тем же элементам массива: например, в случае прямой зависимости, требуется, чтобы обращение по записи выполнялось раньше, чем обращение по чтению. В частности, при решении дополнительных временных ограничений, может оказаться, что они могут быть выполнены, если обрабатываемые в программе массивы будут разбиты на блоки. При этом смежные блоки должны быть распределены по процессорам «с перекрытием», чтобы все необходимые 15
данные были на каждом из процессоров. При этом возникают так называемые теневые грани (т.е. части массива, используемые на данном процессоре, а вычисляемые на соседнем процессоре). Ширина теневых граней определяется алгоритмом решения задачи и определяет фактический объем передаваемых в сети сообщений. Количество теневых граней зависит выбора способа нумерации процессоров: априорно выгоднее всего, чтобы размерность массива процессоров совпадала с размерностью обрабатываемых массивов данных. Однако в некоторых случаях оказывается более выгодным, чтобы размерность массива процессоров была меньше, чем размерность обрабатываемых массивов данных. Пример 1. В качестве примера работы инструмента “DataDistr” рассмотрим цикл: for (i = 1; i : op<delete>_begin(), op<delete>_end(boolean) 1 Integer x = null; 2 boolean b = false; 3 4 boolean delete() { 5 synchronized(this) { 6 if(x!=null && b) {//3_T 7 x = null; 8 b = false; 9 return true; 10 } else {//3_F1, 3_F2 11 return false; 12 } 13 } 14 }
t i (α i ) < t j (α j ) , если t i (α i ) в трассе лежит раньше t j (α j ) и
выполнено одно из условий: o t i , t j ≠ {op_begin, op_end}, (t1 , t 2 ) ∈ D и α i ≠ α j o •
t i = op_end, t j = op_begin и ti , t j не принадлежат
одной операции. t i (α i ) = t j (α j ) , если α i = α j и ti , t j принадлежат одной
операции. Утверждение 1. Пусть в трассе σ последовательно встречаются t i (α i ), t j (α j ) и t i (α i ) ≤/ t j (α j ) . Пусть σ ' это трасса, полученная из
σ
перестановкой t i (α i ), t j (α j ) в обратном порядке. Тогда история трассы эквивалентна истории трассы
σ
σ'
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
boolean insert(int i) { boolean r = false; synchronized(this) { if(x==null) {//1_T x = i; r = true; }//1_F } synchronized(this) { if(r) {//2_T b = true; return true; } else {//2_F return false; } } }
( H (σ ' ) = H (σ ) ). Рис. 1. Код программы Cell
Следует из того, что t i (α i ), t j (α j ) независимы, так как t i (α i ) ≤/ t j (α j ) . Последовательность по отношению следования – это последовательно переходов связанных отношениями по определению 6: t i1 (α i1 ) ≤ t i2 (α i2 ) ≤ L ≤ t i p (α i p ) , где t i j (α i j ) – элементы трассы. Цикл – это последовательность t i1 (α i1 ) < t i2 (α i2 ) ≤ L < t i p (α i p ) , в которой t i1 (α i1 ) = t i p (α i p ) и t i1 (α i1 ) лежит раньше t i p −1 (α i p −1 ) .
Утверждение 2 рассмотрим в данной статье без доказательства. Утверждение 2. Если в достижимых трассах нет циклов, то программа самолинеаризуема.
Программа реализует ячейку, в которой хранится целочисленное значение. Операция insert записывает целочисленный элемент в ячейку и возвращает true, если ячейка свободна, иначе возвращает false. Операция delete удаляет элемент из ячейки и возвращает true, если ячейка не пуста, иначе возвращает false. В нашем простом примере операция insert специально немного усложнена, для того чтобы продемонстрировать трудности, встречающиеся в более сложных программах.
5.1. Предусловие применения Для применения метода Sapsan требуется, чтобы программа удовлетворяла дисциплине синхронизации доступа к разделяемым переменным. Суть этой дисциплины заключается в том, что доступ к любой переменной из разных потоков должен быть защищен хотя бы одним общим объектом-монитором. Это условие гарантирует отсутствие состояний гонок (race conditions) в 95
96
программе. Проверка следования данной дисциплине может осуществляться одним из известных алгоритмов [8,21]. Следование данной дисциплине позволяет рассматривать в качестве переходов программы не отдельные инструкции, а целые последовательности инструкций, называемые блоками, ограниченные входами и выходами из объектов-мониторов. В примере Cell используется две разделяемые переменные x и b. Каждое обращение к этим переменным защищено объектом-монитором this. Поэтому дисцилина синхронизации выполнена.
5.2. Шаг 1. Инструментация Инструмент Sapsan инструментирует программу, т.е. вставляет в скомпилированный код программы дополнительные инструкции. Вместе с основным кодом программы должны быть инструментированы все используемые им библиотеки, в том числе поставляемые с виртуальной машиной Java, на которой будет происходить выполнение. Инструмент вставляет перехваты начала и конца операций, входа и выхода из объектамонитора. Вставляет код для отслеживания результатов проверки условий в условных выражениях и записи в поля объектов. Инструментация необходима для сохранения трассы выполнения, анализа независимости блоков и управления переключением потоков.
5.3. Шаг 2. Прогон имеющихся тестов
Трассы операций;
3.
Тестовое покрытие.
•
2_F – блок от начала второго входа в монитор (стр. 23) до возврата из операции (стр. 28), выполнение оператора if (стр. 24) идет по ветке false.
•
3_T – блок от начала операции delete (стр. 4) до возврата из операции (стр. 9), выполнение оператора if (стр. 6) идет по ветке true.
•
3_F1 – блок от начала операции delete (стр. 4) до возврата из операции (стр. 11), выполнение оператора if (стр. 6) идет по ветке false, ложен первый операнд конъюнкции (x!=null).
•
3_F2 – блок от начала операции delete (стр. 4) до возврата из операции (стр. 11), выполнение оператора if (стр. 6) идет по ветке false, ложен второй операнд конъюнкции (b).
• op_begin, 1_T, 2_T, op_end<true> • op_begin, 1_F, 2_F, op_end Операция delete: • •
op<delete>_begin, 3_T, op<delete>_end<true> op<delete>_begin, 3_F1, op<delete>_end
5.4. Шаг 3. Оценка покрытия Для того чтобы гарантировать линеаризуемость на данном шаге, мы должны убедиться, что выполнены два требования: 1. Множество трасс операций, выделенное при прогоне тестов, содержит все трассы операций, встречающиеся в трассах выполнений программы.
В примере Cell могут быть выделены блоки: • 1_T – блок от начала операции insert (стр. 15) до второго входа в монитор (стр. 23), выполнение оператора if (стр. 18) идет по ветке true. •
2_T – блок от начала второго входа в монитор (стр. 23) до возврата из операции (стр. 26), выполнение оператора if (стр. 24) идет по ветке true.
Заметим, что блок 3_F2 в последовательных тестах получить мы не можем, т.к. для его появления требуется, чтобы один из потоков выполнил запись в переменную x в операции insert, но не зафиксировал ее присваиванием переменной b значения true. Примеры трасс операций. Операция insert:
Шаги 2-4 выполняются только при наличии готового поставляемого с программой тестового набора. Причем метод не накладывает никаких ограничений на этот тестовый набор. Цель этих шагов – извлечь максимальную пользу из имеющихся тестов. В результате прогона тестов мы получаем: 1. Блоки инструкций; 2.
•
2.
1_F – блок от начала операции insert (стр. 15) до второго входа в монитор (стр. 23), выполнение оператора if (стр. 18) идет по ветке false.
Программа соответствует спецификации на последовательных выполнениях.
Данный шаг метода опирается на уже имеющиеся методы тестирования и оценки полноты тестов. Оценить, покрыли ли все трассы операций, помогает покрытие по путям в графе потока управления (path coverage) [1]. В примере 97
98
Cell оценка данного покрытия поможет выявить отсутствие трасс с блоком 3_F2. Для оценки соответствия спецификации на последовательных выполнениях разработано множество методов. Для примера Cell были разработаны тесты JUnit[26].
5.5. Шаг 4. Проверка достаточных условий На данном шаге запускается инструмент Sapsan, который проверяет, выполнены ли достаточные условия. Инструмент Sapsan выводит начальное отношение зависимости. Независимыми полагаются блоки, не изменяющие разделяемое состояние и блоки, обращающиеся к разделяемым переменным при непересекающихся множествах захваченных объектов мониторов. В примере Cell блоки 1_F, 2_F, 3_F1, 3_F2 независимы между собой, т.к. не изменяют разделяемое состояние. Остальные пары блоков потенциально зависимы. Инструмент ищет циклы. Если цикл найден, то достаточные условия не выполнены, иначе выполнены. В нашем примере циклы будут найдены, например α : 1 _ T < β : 3 _ T < α : 2 _ T = α : 1 _ T .
5.6. Шаг 5. Разработка многопоточных тестов Для использования продвинутых возможностей инструмента Sapsan необходимо разработать специальные тесты. К тестам предъявляются те же требования, что и на шаге 3. Кроме того, тесты обязаны предоставлять следующие возможности: 1. Создавать отдельный поток, в котором была достигнута заданная трасса операции. 2.
Переходить в состояние, в котором начинался тест.
3.
Вычислять конечное состояние.
4.
Проверять соответствие трассы спецификации.
На данный момент разработаны библиотеки, которые позволяют разрабатывать тесты с данными возможностями на основе JUnit и UniTESK[2,3]. Для примера Cell в качестве тестового набора использовались тестовые варианты JUnit. Каждый тестовый вариант testCase состоит из одного вызова операции с некоторыми параметрами. Для тестового варианта задан метод setUp – инициализации состояния и метод tearDown – приведения системы в начальное состояние. В процессе выполнения тестов сохраняется информация о том, каким тестовым вариантом была достигнута данная трасса. Возможность создания 99
отдельного потока обеспечивается библиотекой, которая по сохраненной информации находит тестовый вариант и создает выполняющий его поток. Переход в состояние начала теста обеспечивается методами setUp и tearDown. Для всех тестовых вариантов задан метод getState, вычисляющий текущее состояние системы. За счет этого обеспечивается возможность вычисления конечного состояния. В отличие от обычных тестов JUnit, проверяющих соответствие спецификации прямо в тестовых вариантах (assert…), в многопоточных тестах проверки должны быть вынесены в отдельный метод checkResult. Таким образом, обычный запуск тестового варианта состоит из последовательности: setUp, testCase, getState, checkResult, tearDown.
5.7. Шаг 6. Эвристический анализ программы Эвристический анализ программы включает действия шагов 2 и 4, т.е. тесты выполняются обычным образом, собираются блоки, трассы, покрытие, дальше происходит проверка достаточных условий линеаризуемости. Если они не выполнены, то начинается основная часть эвристического анализа. Как видно из достаточных условий, на их выполнимость оказывает влияние независимость блоков и появление трасс операций в трассах выполнений программы. Чем больше у нас знаний о независимости блоков и непоявлении трасс, тем больше шансов, что достаточные условия будут выполнены. На шаге 4 мы считали независимыми только те блоки, которые были гарантированно независимы. Считали, что любая комбинация из трасс операций составляет трассу выполнения. На этом же шаге инструмент Sapsan уточняет эту информацию эвристическими методами. Более подробно анализ описан в разделе 6. В результате эвристического анализа для примера Cell мы имеем: 1. Установлена независимость блоков (1_T, 1_T), (1_T, 2_T), (2_T, 2_T), (3_T, 3_T), (3_T, 3_F2), (1_T, 2_F), (2_T, 1_F), (2_T, 2_F), (2_T, 3_F1), (3_T, 2_F).
100
2.
Установлена зависимость (1_T, 1_F), (1_T, 3_T), (1_T, 3_F1), (3_F2, 1_T), (3_T, 2_T), (2_T, 3_F2), (3_T, 1_F), (3_F1, 3_T).
3.
Установлено непоявление упорядоченных пар (1_F, 1_T), (1_T, 1_T), (1_T, 2_T), (2_T, 1_T), (1_T, 3_T), (1_T, 3_F1), (3_F2, 1_T), (2_T, 2_T), (3_T, 2_T), (2_T, 3_F1), (3_F1, 2_T), (2_T, 3_F2), (3_T, 1_F), (3_T, 3_T), (3_F1, 3_T), (3_T, 3_F2), (3_F2, 3_T).
4.
Выведено, что блоки 1_T, 2_T, 3_T, 3_F1 не встречаются между блоками 1_T, 2_T.
α :1_ T < β : 3 _ T < α : 2 _ T = α :1_ T , Циклы вида α :1_ T < β : 3 _ F 2 < α : 2 _ T = α :1_ T становятся недостижимыми, остальные невозможны по установленной независимости. Поэтому программа Cell линеаризуема.
Множество трасс операций
Таблица независимости и непоявления
5.8. Шаг 7. Анализ результатов Анализ достаточных условий самолинеаризуемости
Возможно три варианта ответов инструмента «Да», «Нет», «Не удалось установить». Если инструмент выдает ответ «Да», то программа линеаризуема. Если ответ «Нет», то программа не линеаризуема и инструмент выдает трасу выполнения, набор потоков и состояние, на которых нарушается свойство линеаризуемости. Возможен также и третий вариант, когда инструменту не удалось установить линеаризуема ли программа. На выходе в этом случае трассы операций, для которых не выполнены достаточные условия. Эти подозрительные трассы могут быть проанализированы вручную.
Трассы операций, для которых не выполнены достаточные условия
1) Поиск нелинеаризуемого выполнения
2) Установление независимости
6. Эвристический анализ программы Схема работы анализа показана на рис. 2. Для найденных трасс операций проверяются достаточные условия самолинеаризуемости. Если достаточные условия выполнены, то, следовательно, мы показали, что программа линеаризуема. Иначе возможно три варианта: 1. В программе присутствует трасса, на которой нарушается линеаризуемость; 2.
Наша информация о независимости блоков неполна;
3.
Невозможно установить линеаризуемость, используя достаточные условия.
В первом случае нам необходимо попытаться найти подходящую трассу выполнения. Во втором попытаться установить независимость блоков. Эвристический анализ в инструменте Sapsan основан на классических алгоритмах поиска. На входе у алгоритмов программа и набор пользовательских потоков Ψ (см. разд. 3). Имея Ψ , программу можно выполнить и получить какую-то трассу выполнения. В зависимости от чередования инструкций могут получаться разные трассы. Все множество трасс для заданного Ψ – это трассы, полученные при всех возможных чередованиях инструкций потоков. Трасс, как правило, очень много, но не все из них требуются для проверки требуемых свойств. В зависимости от проверяемого свойства выбирается условие эквивалентности трасс. Например, для установления линеаризуемости можно считать эквивалентными трассы с одинаковыми историями. Задача алгоритма поиска – построить полное множество трасс, т.е. множество, содержащее все неэквивалентные трассы. 101
Да
Нет
Не удалось установить
Рис. 2. Установление линеаризуемости
6.1. Алгоритмы поиска В данной работе мы используем алгоритмы, описанные в работе Годфруа [14]. Эти алгоритмы существенно используют понятие независимости для оптимизации поиска. Различают два класса алгоритмов поиска: 1. Алгоритмы с сохранением состояния; 2.
Алгоритмы без сохранения состояния.
Для того чтобы осуществлять поиск, необходимо иметь возможность возвращаться в предыдущее состояние. В существующих алгоритмах это достигается двумя способами. В первом способе, возврат осуществляется восстановлением ранее сохраненного состояния. Он используется в алгоритмах с сохранением состояния. Второй способ, использующийся в алгоритмах без сохранения состояния, заключается в сбросе программы в начальное состояние и перевыполнении до нужного состояния. Для этого требуется наличие соответствующего механизма сброса. Как правило, имея возможность хранить состояния, мы имеем возможность сравнивать их, что может быть использовано для сокращения перебора. Кроме того, сравнение состояний дает возможность обнаруживать циклы в графе 102
переходов. Несмотря на эти преимущества, в данной работе выбран второй способ, потому как хранение состояний, которое потребовалось бы в первом способе обладает рядом недостатков: 1. Требует значительных объемов памяти для хранения состояний 2.
Требует моделирования состояний недоступных для чтения.
Известные алгоритмы, использующие первый способ, реализованы в виде специальной виртуальной машины [5,18,22], которая хранит пройденные состояния и позволяет управлять последовательностью выполнения инструкций. Эти машины с легкостью справляются со всеми инструкциями Java кода. Однако программы на Java, кроме чистого кода содержат вызовы процедур, реализованных на других языках, называемых внутренними (native) методами. Для этих методов требуется написать модель, сохраняющую и восстанавливающую состояния. На практике программы с внутренними методами встречаются часто. Практически все стандартные библиотеки содержат внутренние методы. Например, библиотека работы с сетью. Кроме того, программы часто обращаются к системам, написанным на других языках, например, к базам данных.
6.2. Установление независимости В инструменте Sapsan в качестве основы используется алгоритм поиска достижимых выполнений без сохранения состояний [14], реализованный в инструменте VeriSoft. Этот алгоритм был оснащен возможностью поиска по шаблону, что позволило сократить пространство поиска. Шаблон задает порядок, в котором должны встретиться переходы в искомой трассе. Шаблоны строятся на основе пар путей, для которых не выполнено достаточное условие самолинеаризуемости (Утверждение 2). Поиск по шаблону нацеливается только на трассы, удовлетворяющие шаблону, т.е. трассы выполнения, не подходящие под шаблон, отбрасываются. В примере Cell с помощью поиска по шаблонам было установлено, что следующие пары блоков не появляются ни в одной из трасс: (1_F, 1_T), (1_T, 1_T), (1_T, 2_T), (2_T, 1_T), (1_T, 3_T), (1_T, 3_F1), (3_F2, 1_T), (2_T, 2_T), (3_T, 2_T), (2_T, 3_F1), (3_F1, 2_T), (2_T, 3_F2), (3_T, 1_F), (3_T, 3_T), (3_F1, 3_T), (3_T, 3_F2), (3_F2, 3_T). Из непоявления пар можно сделать вывод о зависимости блоков. Если пара (X,Y) появляется, а в том же состоянии пара (Y,X) – нет, то данная пара является гарантированно зависимой. Отсюда мы получили, что пары (1_T, 1_T), (1_T, 2_T), (2_T, 2_T), (3_T, 3_T), (3_T, 3_F2), (1_T, 2_F), (2_T, 1_F), (2_T, 2_F), (2_T, 3_F1), (3_T, 2_F) – зависимы. Если не появляются обе пары (X,Y) и (Y,X), то пара независима. Так мы получили независимость (1_T, 1_F), (1_T, 3_T), (1_T, 3_F1), (3_F2, 1_T), (3_T, 2_T). Остальные пары (2_T, 3_F2), (3_T, 1_F), (3_F1, 3_T) были признаны независимыми, так как перестановка их местами не меняет конечное состояние ни в одном из выполнений. 103
Метод установки независимости является эвристическим, потому что в общем случае ответить на вопрос, достижимо данное выполнение, невозможно. Поэтому для поиска выбирается ограниченный набор пользовательских потоков Ψ . Ограничения на количество потоков задает пользователь.
7. Результаты применения метода На данный момент метод был успешно применен на нескольких простых примерах, встречающихся в литературе. Были найдены известные ошибки в StringBuffer[11,15] и Vector[23]. Для примера MultiSet из [6] инструмент не смог установить линеаризуемость (MultiSet не самолинеаризуем), но было показано, что параллельное выполнение всех троек операций удовлетворяет спецификации. Кроме того, были написаны многопоточные тесты для реализации кэша Ehcache [25], который оптимизирует доступ к хранящимся в нем элементам, размещая часто используемые элементы в памяти и сохраняя остальные на диске. Реализация этого кэша составляет примерно 40 тысяч строк кода на Java. Было выявлено нарушение достаточных условий и найдено выполнение не соответствующее спецификации.
8. Заключение В работе описан новый метод Sapsan, поддержанный одноименным инструментом, который позволяет автоматизированно проверять свойство линеаризуемости программ. Во введении были рассмотрены различные подходы к проверке линеаризуемости. Было отмечено, что существующие инструменты нацелены на проверку независимых от спецификации свойств. В методе Sapsan, напротив, спецификация является важной составляющей. В эвристическом анализе спецификация позволяет утверждать, что ошибка реально существует, а не просто предупреждать о возможной ошибке. Кроме того, спецификация используется при установлении независимости блоков. По сравнению с инструментами проверки моделей (model checking) метод Sapsan позволяет делать заключение о линеаризуемости программы для произвольного набора пользовательских потоков. Кроме того, алгоритмы эвристического анализа в силу их узкоспециализированной направленности на установление независимости оказываются быстрее классических алгоритмов поиска. Экспериментальные результаты показывают, что метод применим для практически значимых приложений. Литература [1] Борис Бейзер. Тестирование черного ящика. Питер, 2004.
104
[2] Виктор В. Кулямин, Александр К. Петренко, Александр С. Косачев, Игорь Б. Бурдонов. Подход UniTESK к разработке тестов. Программирование, том 29, стр. 25-43, 2003. [3] Алексей В. Хорошилов. Спецификация и тестирование компонентов с асинхронным интерфейсом. Диссертация на соискание ученой степени кандидата физико-математических наук, 2006. [4] Rajeev Alur, Ken Mcmillan, Doron Peled. Model-checking of correctness conditions for concurrent objects. Proceedings of the 11th Annual IEEE Symposium on Logic in Computer Science, стр. 219-228, 1996. [5] Derek Bruening. Systematic testing of multithreaded Java programs. Master's thesis, MIT, 1999. [6] Tayfun Elmas, Serdar Tasiran, Shaz Qadeer. VYRD: verifYing concurrent programs by runtime refinement-violation detection. Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation, стр. 27-37, 2005. [7] Tayfun Elmas, Serdar Tasiran. VyrdMC: Driving Runtime Refinement Checking with Model Checkers. Proceedings of the Fifth Workshop on Runtime Verification, том 144(4), стр. 41-56, 2005. [8] Tayfun Elmas, Shaz Qadeer, Serdar Tasiran. Goldilocks: a race and transaction-aware Java runtime. Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation, стр. 245-255, 2007. [9] Cormac Flanagan, Patrice Godefroid. Dynamic partial-order reduction for model checking software. Proceedings of the 32nd ACM SIGPLAN-SIGACT Symposium on the Principles of Programming Languages, стр. 110-121, 2005. [10] Cormac Flanagan, Stephen N. Freund. Atomizer: A dynamic atomicity checker for multithreaded programs. Proceedings of the ACM Symposium on the Principles of Programming Languages, стр. 256-267, 2004. [11] Cormac Flanagan, Shaz Qadeer. A type and effect system for atomicity. Proceedings of the ACM Conference on Programming Language Design and Implementation, том 38(5), стр. 338-349, 2003. [12] Cormac Flanagan. Verifying commit-atomicity using model-checking. Proceedings of 11th International SPIN Workshop, том 2989, стр. 252-266, 2004. [13] Patrice Godefroid. Partial-order methods for the verification of concurrent systems: an approach to the state-explosion problem. Springer-Verlag, 1996. [14] Patrice Godefroid. Model checking for programming languages using Verisoft. Symposium on Principles of Programming Languages, стр. 174-186, 1997. [15] John Hatcliff, Robby, Matthew B. Dwyer. Verifying atomicity specifications for concurrent object-oriented software using model checking. Proceedings of the Fifth International Conference on Verification, Model Checking and Abstract Interpretation, 2004. [16] Maurice P. Herlihy, Jeannette M. Wing. Linearizability: a correctness condition for concurrent objects. ACM Transactions on Programming Languages and Systems, стр. 463-492, 1990. [17] Leslie Lamport. Specifying concurrent program modules. ACM Transactions on Programming Languages and Systems, том 5(2), стр. 190-222, 1983. [18] Vadim S. Mutilin. Concurrent testing of Java components using Java PathFinder. Second International Symposium on Leveraging Applications of Formal Methods, Verification and Validation, том 2, стр. 53-59, 2006. [19] Christos H. Papadimitriou. The serializability of concurrent database updates. Journal of the ACM, том 26(4), стр. 631-653, 1979.
105
[20] Doron Peled. Combining partial order reductions with on-the-fly model checking. Formal Methods in System Design, том 8, стр. 39-64, 1996. [21] Stefan Savage, Michael Burrows, Greg Nelson, Patrick Sobalvarro, Thomas Anderson. Eraser: A dynamic data race detector for multithreaded programs. ACM Transactions on Computer Systems, том 15(4), стр. 391-411, 1997. [22] Willem Visser, Klaus Havelund, Guillaume Brat, Seungjoon Park, Flavio Lerda. Model checking programs. Automated Software Engineering, том 10(2), стр. 203-232, 2003. [23] Liqiang Wang, Scott D. Stoller. Runtime analysis of atomicity for multithreaded programs. IEEE Transactions on Software Engineering, том 32(2), стр. 93-110, 2006. [24] Liqiang Wang, Scott D. Stoller. Static analysis of atomicity for programs with nonblocking synchronization. Proceedings of the Tenth ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, стр. 61-71, 2005. [25] http://ehcache.sourceforge.net [26] http://www.junit.org
106
Метод формальной спецификации аппаратуры с конвейерной организацией и его приложение к задачам функционального тестирования А.С. Камкин
[email protected] Аннотация. В работе рассматривается метод формальной спецификации аппаратуры с конвейерной организацией, который основан на пред- и постусловиях стадий выполнения операций. Данный метод может быть использован для функционального тестирования моделей аппаратуры, поскольку на основе спецификаций предлагаемого вида можно решать основные задачи тестирования: проверку правильности поведения системы и генерацию тестовой последовательности. Метод был успешно применен для тестирования нескольких модулей промышленного микропроцессора. В результате тестирования были найдены критичные ошибки, не обнаруженные при использовании других подходов.
1. Введение Современные электронные устройства является очень сложными системами, производство которых можно начинать только после тщательного проектирования. Проектирование электроники осуществляется с помощью специализированных языков описания аппаратуры (HDLs, Hardware Description Languages), например, Verilog или VHDL [1], позволяющих абстрагироваться от деталей расположения и соединения отдельных элементов электронной схемы. Проект устройства на таком языке является исполнимой программой, у которой имеются параметры, соответствующие входам устройства, и называется моделью1. После окончания проектирования
1
Такие модели также называют HDL-моделями или RTL-моделями, поскольку проектирование ведется на уровне регистровых передач (RTL, Register Transfer Level). 107
модель преобразуется в точное описание расположения и соединения друг с другом отдельных элементов электронной схемы устройства. Поскольку современное аппаратное обеспечение является очень сложным, при его проектировании часто делаются ошибки. Ошибка проектирования впоследствии может проявиться как некорректное, несоответствующее требованиям поведение устройства в определенной ситуации. Ошибки в аппаратуре способны приносить огромный ущерб, однако их исправление в уже изготовленном устройстве практически невозможно и требует колоссальных затрат [2]. Поэтому большую часть ошибок крайне желательно выявить и исправить еще в процессе проектирования, при разработке модели. Для проверки корректности моделей аппаратуры используют различные методы функциональной верификации [3, 4]. Наиболее широко используемым на практике методом верификации является имитационное тестирование (simulation-based verification)2. Этот метод состоит в программной имитации работы устройства, описываемого моделью, с помощью симулятора, в рамках ряда специально разработанных тестовых сценариев, которые представляют собой основные варианты использования функций этого устройства, возможные при его эксплуатации. Главной задачей тестирования является проверка соответствия поведения системы предъявляемым к ней требованиям. Для возможности автоматизации такой проверки требования к системе должны быть представлены в машиночитаемой форме, которую называют формальными спецификациями. Настоящая работа посвящена формальной спецификации аппаратуры с конвейерной организацией. В общих словах, конвейерная организация означает, что в один и тот же момент времени устройство может обрабатывать сразу несколько операций, однако поток операций, подаваемых на выполнение, является последовательным [5]. Конвейерная обработка является основным способом повышения производительности разного рода устройств; в частности, по такому принципу проектируются микропроцессоры, их модули и подсистемы. В статье рассматривается метод формальной спецификации конвейерной аппаратуры, основанный на пред- и постусловиях стадий выполнения операций, и описывается его приложение к задачам функционального тестирования. Несколько слов о том, как организована статья. Во втором разделе, который начинается сразу за этим абзаца, даются общие сведения об аппаратуре с конвейерной организацией. Третий раздел описывает предлагаемый метод формальной спецификации. В четвертом разделе описывается применение метода для решения задач тестирования: проверки правильности поведения и генерации тестовой последовательности. Пятый раздел содержит сравнение 2
В дальнейшем для краткости будем называть имитационное тестирование аппаратуры просто тестированием, хотя под тестированием обычно понимается проверка готовой микросхемы. 108
рассматриваемого метода с существующими подходами. В шестом разделе описывается практическая апробация подхода. Наконец, в последнем, седьмом разделе делается заключение и очерчиваются направления дальнейших исследований.
2. Аппаратура с конвейерной организацией Модели аппаратуры на HDL-языках представляют собой системы из нескольких взаимодействующих модулей. Как и в традиционных языках программирования, модули используются для декомпозиции сложной системы на множество независимых или слабо связанных подсистем. Каждый модуль имеет интерфейс – набор входов и выходов, через которые осуществляется соединение модуля с окружением, и реализацию, определяющую способ обработки модулем входных сигналов: вычисление значений выходных сигналов и изменение внутреннего состояния. Для удобства будем считать, что спецификация и тестирование осуществляются на уровне отдельных модулей. Как правило, модули цифровой аппаратуры работают синхронно под управлением тактового сигнала. Фронты тактового сигнала разбивают непрерывное время на дискретный набор интервалов, называемых тактами. Что делать модулю на текущем такте, определяется значениями входных сигналов и внутренним состоянием модуля. Часть входов модуля определяет операцию, которую модулю следует выполнить, – такие входы называются управляющими; другая часть определяет аргументы операции, – такие входы называются информационными. Среди реализуемых модулем операций обычно присутствует «пустая» операция NOP (No Operation), означающая бездействие, отсутствие операции. Состояние модуля также можно разбить на две составляющие: состояние управления и состояние данных. Первая из них является частью управляющей логики модуля и используется для управления процессами выполнения операций. Состояние данных, как видно из названия, представляет собой внутренние данные модуля. Рассмотрим, как осуществляется выполнение модулем однотактной операции (см. рис. 1). До начала очередного такта окружение устанавливает код операции и аргументы на соответствующих входах модуля (на рис. 1 – сигнал подачи операции). Операция запускается с началом такта. За этот такт модуль производит необходимые вычисления, изменяет внутреннее состояние и устанавливает значения выходных сигналов, которые окружение может использовать, начиная со следующего такта (результат операции).
Рис. 1. Временная диаграмма сигналов для однотактной операции. В отличие от однотактной операции, результат многотактной операции вычисляется постепенно такт за тактом. Пусть операция A выполняется модулем за L тактов. Тогда на каждом такте i ∈ {1, ..., L} модуль выполняет некоторую микрооперацию Ai, а окружение после окончания каждого такта получает некоторый частичный результат. Представление многотактной операции A в виде последовательности микроопераций (A1, ..., AL) называется декомпозицией операции A на стадии3. В этой статье акцент делается на конвейерные модули, то есть модули, в которых операции подаются на выполнение последовательно одна за другой, но процессы их выполнения могут пересекаться по времени (см. рис. 2). Такие модули широко распространены, особенно в практике проектирования микропроцессоров. Можно выделить два типа конвейеров: конвейеры без блокировок (pipelines without interlocked stages) и конвейеры с блокировками (pipelines with interlocked stages). В конвейерах первого типа выполнение последовательных стадий, относящихся к одной операции, осуществляется на последовательных тактах: если стадия Ai была выполнена на такте j, то стадия Ai+1 будет выполнена на такте j+1. В конвейерах второго типа это свойство, вообще говоря, не выполнено – между тактами, на которых выполняются последовательные стадии, могут быть задержки: если стадия Ai была выполнена на такте j, то стадия Ai+1 будет выполнена на такте j+1+δ, где δ ≥ 0 – величина задержки между стадиями, которая определяется на основе состояния управления модуля. 3
109
В данной статье термины «стадия» и «микрооперация» являются синонимами. 110
3.1. Вспомогательные понятия Введем основные понятия теории автоматов, на которых базируется контрактная спецификация конвейера. Определение. Автоматом называется четверка 〈S, X, Y, T〉, в которой: •
S – множество состояний;
•
X – множество стимулов;
•
Y – множество реакций;
•
T ⊆ S × X × Y × S – отношение переходов. Каждый переход t ∈ T имеет вид (st, xt, yt, s't), где:
Рис. 2. Выполнение двух операций на конвейере. Блокировки в конвейере предназначены для того, чтобы избежать конфликтов использования ресурсов между операциями и сохранить целостность потока данных. Например, в приведенной ниже ассемблерной программе инструкция add складывает содержимое регистра r2 с содержимым регистра r3 и сохраняет результат в регистре r1. Следом за ней идет инструкция sub, которая использует значение регистра r1. В этом случае доступ к регистру r1 из инструкции sub блокируется до тех пор, пока инструкция add не запишет в него результат – в противном случае инструкция sub считает некорректное значение. add r1, r2, r3 // запись в регистр r1 sub r4, r1, r5 // чтение из регистра r1 Конвейерная организация аппаратуры позволяет увеличить производительность, но одновременно привносит сложность в реализацию, что сказывается и на сложности тестирования. Во-первых, усложняется проверка правильности поведения системы, поскольку стадии разных операций могут перекрываться по времени и это необходимо учитывать. Вовторых, из-за наличия нетривиальной управляющей логики увеличивается пространство состояний, что усложняет построение тестовой последовательности.
3. Формальная спецификация конвейера В данном разделе рассматривается метод формальной спецификации аппаратуры с конвейерной организацией, основанный на пред- и постусловиях стадий выполнения операций. Формальные спецификации предлагаемого вида называются контрактными спецификациями конвейера.
111
•
st ∈ S – пресостояние;
•
xt ∈ X – стимул;
•
yt ∈ Y – реакция;
•
s't ∈ S – постсостояние.
Модель автомата, расширенная контекстными переменными, входными параметрами стимулов, выходными параметрами реакций, предикатами и функциями переходов, определенными над контекстными переменными и входными параметрами, называется расширенным автоматом. Расширенные автоматы широко используются в информатике для моделирования программных и аппаратных систем. Обычно считают, что автомат, лежащий в основе расширенного автомата, моделирует управляющую логику системы, а контекстные переменные, параметры и функции, определенные над ними, – потоки данных. Для удобства объединим контекстные переменные и параметры расширенного автомата общим термином переменные. В последующих определениях будем считать, что для каждой переменной v задано множество возможных значений Domv, называемое доменом переменной v. Определение. Пусть V – некоторое множество переменных. Функцией означивания переменных из V называется отображение ν, которое каждой переменной x ∈ V ставит в соответствие ее значение ν(x) ∈ Domx. Множество всех функций означивания переменных из V будем обозначать символом DomV и называть множеством значений переменных из V. Определение. Расширенным автоматом называется шестерка 〈S, V, I ∪ O, X, Y, T〉, в которой:
112
•
S – множество состояний;
•
V – множество контекстных переменных;
Функция означивания контекстных переменных называется контекстом расширенного автомата. •
I ∪ O ⊆ V – множество входных и выходных параметров; Заметим, что в данном определении множество входных и выходных параметров является подмножеством множества контекстных переменных.
•
X – множество стимулов; С каждым стимулом x ∈ X связано множество входных параметров Inx ⊆ I. Множество значений входных параметров стимула x будем обозначать Domx.
•
Y – множество реакций;
•
T – отношение переходов. С каждым переходом t ∈ T связаны два подмножества множества контекстных переменных: o
Uset ⊆ V \ O переменных;
o
Deft ⊆ V \ I – множество определяемых контекстных переменных.
–
множество
используемых
контекстных
Каждый переход t ∈ T имеет вид (st, xt, yt, γt, δt, s't), где: o
st ∈ S – пресостояние;
o
xt ∈ X – стимул;
o
yt ∈ Y – реакция;
o
γt: Domx × DomUse → {true, false} – охранный предикат;
o
δt: Domx × DomUse → DomDef – функция обновления контекста;
o
s't ∈ S – постсостояние.
pres, x(p, ν) = ∨γ ∈ Сond(s, x) γ, где Cond(s, x) = {γt | st = s, xt = x}. Если Cond(s, x) = ∅, pres, x полагается равным false. Определение. Пара x[p], состоящая из стимула x и набора значений его входных параметров p, называется инициализированным стимулом. Множество всех инициализированных стимулов будем обозначать символом Param(X). Аналогичное определение и связанные с ними обозначения имеют место и для переходов расширенного автомата. Определение. Пара t[p], состоящая из перехода t и набора значений входных параметров p соответствующего стимула xt называется инициализированным переходом. Определение. Инициализированный переход t[p] называется допустимым в конфигурации (s, ν), если st = s, xt ∈ Init(s) и γt(p, ν) = true. Расширенный автомат функционирует следующим образом. Находясь в некоторой конфигурации, он получает инициализированный стимул и вычисляет множество допустимых инициализированных переходов. После этого он выполняет один из переходов, недетерминированно выбранный из вычисленного множества. В процессе выполнения расширенный автомат изменяет значения входных параметров, обновляет контекст и переходит из пресостояния в постсостояние.
3.2. Спецификация конвейера без блокировок Для наглядности сначала определим контрактную спецификацию для случая конвейера без блокировок. Определение. Контрактной спецификацией конвейера без блокировок длины L называется шестерка 〈V, ν0, I ∪ O, X ∪ {τ}, Z ∪ {ε}, ρ〉, в которой:
Определение. Конфигурацией расширенного автомата называется пара (s, ν) ∈ S × DomV, состоящая из состояния и контекста. В дальнейшем будем рассматривать расширенные автоматы c выделенной начальной конфигурацией (s0, ν0). Такие автоматы называются инициальными и описываются семерками 〈S, V, (s0, ν0), I ∪ O, X, Y, T〉. Будем использовать следующие обозначения: Tran(s) = {t ∈ T | st = s} Init(s) = {xt | t ∈ Tran(s)} Определение. Предусловием стимула x в состоянии s называется предикат pres, x: Domx × DomV → {true, false}, определяемый равенством 113
•
V – множество контекстных переменных;
•
ν0 ∈ DomV – начальный контекст;
•
I ∪ O ⊆ V – множество входных и выходных параметров;
•
X ∪ {τ} – множество стимулов; С каждым стимулом x ∈ X ∪ {τ} связано множество входных параметров Inx ⊆ I. Множество значений входных параметров стимула x будем обозначать Domx. Множество PL = (X ∪ {τ})L называется множеством состояний управления, а его элемент π0 = (τ, ..., τ) – начальным состоянием управления. Для каждого стимула x также заданы: •
114
γx: PL → {true, false} – охранный предикат стимула;
•
prex: Domx × DomV → {true, false} – предусловие стимула.
Множество стимулов включает выделенный стимул τ, называемый тактовым стимулом, для которого выполнены следующие свойства:
•
•
Inτ = ∅;
•
γτ ≡ true;
•
preτ ≡ true.
Z ∪ {ε} – множество стадий; •
Usez ⊆ V \ O переменных;
•
Defz ⊆ V \ I – множество определяемых контекстных переменных;
•
postz: DomUse × DomDef → {true, false} – постусловие стадии.
множество
используемых
контекстных
Множество стадий включает выделенную стадию ε, называемую пустой стадией, для которой выполнены следующие свойства:
•
•
Useε = ∅;
•
Defε = ∅;
•
postε ≡ true.
•
Usey ∩ Defz ≠ ∅ – конфликт типа «чтение-запись»;
•
Defy ∩ Defz ≠ ∅ – конфликт типа «запись-запись».
Если ни для каких стадий y ≠ z ни одно из перечисленных условий не выполнено, множество стадий называется согласованным.
Для каждой стадии z заданы: –
предшествующие; оператор связывания стадий конвейера возвращает множество стадий, выполняемых в текущем состоянии управления. Определение. Множество стадий называется конфликтным, если для некоторых стадий y ≠ z из этого множества выполнено хотя бы одно из следующих условий:
ρ: X ∪ {τ} → (Z ∪ {ε})L – функция композиции операций.
Определение. Состояние управления π называется согласованным, если для всех 1 ≤ i ≠ j ≤ L, таких что ρi(πi) ≠ ε и ρj(πj) ≠ ε, выполняется ρi(πi) ≠ ρj(πj) и множество стадий θ(π) является согласованным. Определение. Контрактная спецификация конвейера называется согласованной, если для всех стимулов x и состояний управления π из того, что π согласованно и γx(π) = true, вытекает, что x ° π согласованно. В дальнейшем будем рассматривать только согласованные контрактные спецификации конвейера. Пусть Σ = 〈V, ν0, I ∪ O, X ∪ {τ}, Z ∪ {ε}, ρ〉 – контрактная спецификация конвейера без блокировок длины L. Ее можно интерпретировать как инициальный расширенный автомат Δ = 〈S, V, (π0, ν0), I ∪ O, X ∪ {τ}, Y ∪ {ξ}, T〉 с выделенными тактовым стимулом τ и пустой реакцией ξ, устроенный следующим образом:
Последовательность стадий ρ(x) называется операцией стимула x. Функция ρ обладает следующим свойством: ρ(τ) = (ε, ..., ε)4. Для интерпретации контрактной спецификации конвейера будем использовать оператор сдвига конвейера и оператор связывания стадий конвейера. Определение. Функция °: (X ∪ {τ}) × PL → PL, определяемая равенством x0 ° (x1, ..., xL) = (x0, ..., xL-1), называется оператором сдвига конвейера. Определение. Функция θ: PL → 2Z, определяемая равенством θ(π) = {ρ1(π1), ..., ρL(πL)} \ {ε}, называется оператором связывания стадий конвейера. Смысл этих операторов достаточно прост: оператор сдвига конвейера добавляет в начало конвейера новый стимул, сдвигая при этом
S = PL – состояниями расширенного автомата Δ являются состояния управления контрактной спецификации Σ;
•
π0 = (τ, ..., τ) – начальным состоянием является начальное состояние управления;
•
Y = 2Z – реакциями расширенного автомата Δ являются множества стадий контрактной спецификации Σ;
•
ξ = ∅ – пустой реакцией является пустое множество стадий;
•
отношение переходов T расширенного автомата Δ для всех π ∈ S и x ∈ X ∪ {τ} таких, что γx(π) = true, содержит все возможные переходы t = (π, x, y, γ, δ, π'), в которых: •
4
Стимул τ и соответствующая ему последовательность пустых стадий (ε, ..., ε) формализуют операцию NOP. 115
•
116
Uset = ∪z ∈ θ(π')Usez
множество используемых контекстных переменных получается объединением соответствующих множеств для стадий из θ(π'); •
Deft = ∪z ∈ θ(π')Defz множество определяемых контекстных переменных получается объединением соответствующих множеств для стадий из θ(π');
•
π' = x ° π
Определение. Состоянием управления называется множество состояний обработки стимулов. Пустое множество состояний обработки стимулов называется начальным состоянием управления. Множество всевозможных состояний управления для конвейера длины L будем обозначать символом PL. Определение. Контрактной спецификацией конвейера с блокировками длины L называется шестерка 〈V, ν0, I ∪ O, X ∪ {τ}, Z ∪ {ε}, ρ〉, в которой:
постсостояние получается сдвигом конвейера; •
y = θ(π') реакция определяется как результат связывания стадий, выполненного в постсостоянии перехода;
•
•
•
V – множество контекстных переменных;
•
ν0 ∈ DomV – начальный контекст;
•
I ∪ O ⊆ V – множество входных и выходных параметров;
•
X ∪ {τ} – множество стимулов;
γ(p, ν) = prex(p, ν)
Для каждого стимула x ∈ X ∪ {τ} заданы:
охранный предикат определяется как предусловие соответствующего стимула;
•
Inx ⊆ I – множество входных параметров;
•
γx: PL → {true, false} – охранный предикат стимула;
•
prex: Domx × DomV → {true, false} – предусловие стимула.
результирующий контекст ν' = δ(p, ν) для всех ν ∈ DomV, таких что prex(p, ν) = true, удовлетворяют предикату:
Φπ, x(p, ν, ν') = ∨z ∈ θ(π') postz(ν|Use, ν'|Def). Определение. Предикат Φπ, x(p, ν, ν') называется тестовым оракулом стимула x в состоянии управления π. Тестовому оракулу отводится основная роль в проверке правильности поведения тестируемого устройства (см. раздел «Проверка правильности поведения»).
•
Для каждой стадии z ∈ Z ∪ {ε} заданы:
Определение. Автомат, лежащий в основе расширенного автомата Δ(Σ), интерпретирующего контрактную спецификацию Σ, называется управляющим автоматом спецификации Σ и обозначается Ω(Σ). Управляющий автомат является формальной моделью управляющей логики устройства. На основе обхода графа состояний управляющего автомата осуществляется генерация тестовой последовательности (см. подраздел 4.2). •
3.3. Спецификация конвейера с блокировками Обобщим введенное ранее понятие контрактной спецификации на случай конвейера, в котором возможны блокировки. Дадим несколько вспомогательных определений. Определение. Состоянием обработки стимула или процессом называется пара (x, l), в которой: •
x ∈ X ∪ {τ} – обрабатываемый стимул;
•
l ∈ {1, ..., L} – номер стадии обработки стимула. 117
Z ∪ {ε} – множество стадий; •
Usez ⊆ V \ O переменных;
•
Defz ⊆ V \ I – множество определяемых контекстных переменных;
•
γz: PL → {true, false} – охранный предикат стадии;
•
postz: DomV × DomV → {true, false} – постусловие стадии.
–
множество
используемых
контекстных
ρ: X ∪ {τ} → (Z ∪ {ε})L – функция композиции операций.
Заметим, что по сравнению с определением контрактной спецификации конвейера без блокировок в данном определении появились охранные предикаты стадий – именно они используются для описания блокировок конвейера. Определение. Процесс (x, l) называется активным в состоянии управления π, если γz(π) = true, где z = ρl(x). В противном случае процесс называется заблокированным. 118
Определение. Множество Enabled(π) = {(x, l) ∈ π | γz(π) = true, где z = ρl(x)} называется множеством активных процессов в состоянии управления π. Определение. Множество Locked(π) = π \ Enabled(π), являющееся дополнением множества Enabled(π), называется множеством заблокированных процессов в состоянии управления π. Отличие в интерпретации контрактной спецификации конвейера с блокировками по сравнению со случаем без блокировок заключается в измененной семантике операторов сдвига конвейера и связывания стадий. Определение. Функция °: (X ∪ {τ}) × PL → PL, которая для всех пар (x, π) принимает значение x ° π, равное объединению следующих множеств: •
Locked(π);
•
{(x, l+1) | (x, l) ∈ Enabled(π) ∧ l < L};
•
{(x, 1)}, если x ≠ τ; ∅, если x = τ.
называется оператором сдвига конвейера. Определение. Функция θ: PL → 2Z, определяемая равенством θ(π) = {ρl(x) | (x, l) ∈ Enabled(π)} \ {ε}, называется оператором связывания стадий конвейера.
4. Приложение к задачам тестирования Рассмотрим применение контрактных спецификаций конвейера для решения основных задач тестирования: проверки правильности поведения и генерации тестовой последовательности.
4.1. Проверка правильности поведения Определим отношение соответствия между контрактными спецификациями конвейера и инициальными расширенными автоматами5. Рассмотрим контрактную спецификацию Σ = 〈VS, ν0S, IS ∪ OS, XS ∪ {τS}, ZS ∪ {εS}, ρS〉 конвейера без блокировок длины L и инициальный расширенный автомат Δ = 〈SI, VI, (s0I, ν0I), II ∪ OI, XI ∪ {τI}, YI ∪ {ξI}, TI〉 с выделенными тактовым стимулом τI и пустой реакцией ξI. Введем несколько вспомогательных понятий. Определение. Сюрьективное отображение ϕS→: PLS → SI, обладающее свойством ϕS→(∅) = s0I, называется функцией соответствия состояний.
5
Для возможности формального определения отношения соответствия предполагается, что реализация описывается расширенным автоматом. 119
Определение. Отображение ϕX→: Param(XS ∪ {τS}) → Param(XI ∪ {τI}), → S обладающее тем свойством, что ϕX (x ) = τI тогда и только тогда, когда xS = τS называется функцией соответствия стимулов. Определение. Биективное отображение ϕY←: YI ∪ {ξI} → 2Z, где Z = ZS, обладающее тем свойством, что ϕY←(yI) = ∅ тогда и только тогда, когда yI = ξI называется функцией соответствия реакций. Определение. Отображение ϕV←: DomV(I) → DomV(S), где V(I) = VI и V(S) = VS, обладающее свойством ϕV←(ν0I) = ν0S, называется функцией соответствия контекстов. Определение. Будем говорить, что инициальный расширенный автомат соответствует контрактной спецификации для заданных функций соответствия 〈ϕS→, ϕX→, ϕY←, ϕV←〉, если для всех πS ∈ PLS, S S S S I S x [p ] ∈ Param(X ∪ {τ }) и ν ∈ DomV(I) из того, что γx(π ) = true, вытекает, что xI ∈ Init(sI), причем если prex(pS, νS) = true, то pres, x(pI, νI) = true, где sI = ϕS→(πS), xI[pI] = ϕX→(xS[pS]) и νS = ϕV←(νI), при этом для каждого выполнено инициализированного перехода tI[pI] ∈ Enabled(sI, xI, νI) S S → ← s't = ϕS (π' ), ϕY (yt) = θ(π' ) и Φπ, x(pS, νS, ν'S) = true, где π'S = xS ° πS и ν'S = ϕV←(ν't). Заметим, что реализация может содержать неспецифицированные переходы, то есть переходы, в которых для определенного набора значений входных параметров и контекста выполнен охранный предикат, но для всех соответствующих стимулов спецификации нарушается либо охранный предикат, либо предусловие. Таким образом, контрактная спецификация Σ для каждого инициального расширенного автомата Δ и заданного набора функций соответствия ϕ определяет подавтомат, состоящий только из специфицированных переходов, который будем называть спецификационным подавтоматом. Проверка правильности поведения осуществляется для заданных функций соответствия, которые выполняют функции преобразования данных из спецификационного представления в реализационное (ϕS→ и ϕX→) и наоборот из реализационного представления в спецификационное (ϕY← и ϕV←). Компоненты тестовой системы, которые реализуют такие функции, называются адаптерами. Схема проверки правильности поведения, приведенная ниже, основана на определении отношения соответствия: (πS, νS) ← (∅, ν0S); if(sI ≠ ϕS→(πS) ∨ νS ≠ ϕV←(νI)) { error(«Ошибка инициализации»); } // пока тест не завершен while(¬isTestComplete()) { // получить очередной стимул от тестовой системы xS[pS] ← getNextStimulus(); 120
// проверить выполнимость охранного предиката и предусловия стимула if((γx(πS) ∧ prex(pS, νS)) { // преобразовать стимул в реализационное представление xI[pI] ← ϕX→(xS[pS]); // подать стимул на реализацию applyStimulus(xI[pI]); // подождать один такт waitOneCycle(); // получить состояния, реакцию и контекст реализации sI ← getState(); yI ← getReaction(); νI ← getContext(); // преобразовать реакцию/контекст в реализационное представление yS ← ϕY←(yI); ν'S ← ϕV←(νI); // вычислить новое состояние управления πS ← xS ° πS; if(sI ≠ ϕS→(πS)) { error(«Ошибка несоответствия состояний»); } if(yS ≠ θ(πS)) { error(«Ошибка несоответствия реакций»); } if(¬Φπ, x(pS, νS, ν'S)) { error(«Ошибка несоответствия контекстов»); } } } В представленной выше схеме проверки используются следующие обобщенные функции тестовой системы: • isTestComplete – проверяет завершена ли генерации тестовой последовательности; •
getNextStimulus – получает очередной инициализированный стимул от генератора тестовой последовательности;
•
applyStimulus – подает инициализированный стимул на реализацию;
•
waitOneCycle – ожидает один такт;
•
getState – получает состояние управления реализации;
•
getReaction – получает реакцию реализации;
•
getContext – получает контекст реализации.
Часто при тестировании состояние управления реализации является скрытым (либо к нему отсутствует доступ, либо доступ есть, но от деталей реализации управляющей логики целесообразно абстрагироваться), поэтому функция 121
получения состояния управления getState и функция соответствия состояний ϕS→ неопределенны. В этом случае проверки вида sI ≠ ϕS→(πS) опускаются. Сравнение yS ≠ θ(πS) также не осуществляется, поскольку реакции устройства (внутренние действия по обработке стимулов), как правило, не наблюдаемы. Проверки, которые выполняются на практике, базируются на предикате Φπ, x(pS, νS, ν'S), то есть на наблюдении за изменениями контекста (состояния данных и выходов модуля). В схеме проверки правильности поведения заложена следующая классификация ошибок в модулях микропроцессоров: ошибки несоответствия состояний, ошибки несоответствия реакций и ошибки несоответствия контекстов. Ошибки несоответствия состояний являются формализацией ошибок в управляющей логике. Именно на обнаружения ошибок этого типа в первую очередь нацелен предлагаемый метод автоматизации тестирования. Поскольку проверки правильности поведения основаны на предикате Φπ, x, предполагается, что ошибки несоответствия состояний проявляются в некорректном изменении контекста, в частности, выходов модуля.
4.2. Генерация тестовой последовательности Основная особенность конвейерных модулей заключается в сложной организации управляющей логики. В данном разделе рассматривается метод генерации тестовой последовательности, нацеленный на создание различных ситуаций именно в управляющем компоненте модуля. Метод основан на контрактных спецификациях конвейера. Пусть задана спецификация Σ = 〈V, ν0, I ∪ O, X ∪ {τ}, Z ∪ {ε}, ρ〉. Определение. Тестовой последовательностью для контрактной спецификации Σ называется произвольная последовательность переходов расширенного автомата Δ(Σ), интерпретирующего спецификацию Σ, допустимая в начальной конфигурации (∅, ν0). Формализацией управляющей логики модуля, описываемого спецификацией Σ, является управляющий автомат Ω(Σ). С точки зрения спецификации цель тестирования задается как покрытие всех достижимых состояний управляющего автомата. Предлагаемый метод генерации тестовой последовательности основан на обходе графа состояний управляющего автомата. Для обхода мы используем неизбыточные алгоритмы, то есть алгоритмы, для работы которых достаточно информации о пройденном подграфе. Входной информацией неизбыточных алгоритмов обхода графов является неизбыточное описание графа [6] Определение. Неизбыточным описанием графа состояний называется тройка 〈V, X, enabled〉, где: • 122
V – множество вершин;
•
X – множество стимулов;
•
enabled: V → 2X – функция, которая для каждой вершины графа возвращает множество допустимых в ней стимулов.
В работах [6-9] исследованы неизбыточные алгоритмы обхода разных классов графов. В частности, в статье [8] рассмотрен неизбыточный алгоритм обхода αdfsm6 на классе детерминированных сильно-связных конечных графов, а в [6] – алгоритм αndfsm на классе графов, имеющих детерминированный сильносвязный полный остовный подграф. Следует отметить, что алгоритм αndfsm применяется и в тех случаях, когда граф заведомо детерминирован. Дело в том, что этот алгоритм относится к «жадным» алгоритмам и в ряде случаев позволяет значительно сократить длину тестовой последовательности. Заметим, что управляющий автомат является конечным (если множество стимулов конечно) и детерминированным. Несложно показать, что граф состояний управляющего автомата является сильно-связным, если в нем нет тупиковых состояний, то есть состояний π ≠ ∅, таких, что Enabled(π) = ∅ (на практике это условие тоже выполнено – наличие тупикового состояния сигнализирует об ошибке в спецификации). Таким образом, условия применения неизбыточных алгоритмов выполнены. Неизбыточное описание графа состояний управляющего автомата имеет вид 〈PL, X ∪ {τ}, enabled〉, где множество допустимых стимулов для каждого состояния π определяется следующим образом: enabled(π) = {x ∈ X ∪ {τ} | γx(π) = true}. При тестировании управляющей логики конкретные значения параметров стимулов не важны – можно использовать любые значения, удовлетворяющие соответствующему предусловию. В предложенном методе предполагается, что для любого стимула x и контекста ν существует набор параметров p ∈ Domx, который удовлетворяет условию prex(p, ν) = true. На практике это не всегда так, то есть возможны ситуации, когда для некоторого стимула x существует контекст ν, для которого не существует значений параметров, удовлетворяющих предусловию. Получается, что в одном и том же состоянии управляющего автомата в некоторых ситуациях предусловие стимула выполнено, а в некоторых нет. Эта проблема решается добавлением в состояние обходимого графа конвейера дополнительной информации, на основе которой определяется выполнимость предусловий.
5. Сравнение с существующими подходами В данном разделе приводится сравнение предлагаемого метода спецификации и тестирования аппаратуры с конвейерной организацией с существующими 6
В указанной работе этот алгоритм обозначается символом A2.
123
подходами. Сравнение разбито на две части: в первой из них сравниваются методы спецификации, во второй – методы генерации тестовой последовательности.
5.1. Методы спецификации аппаратуры В настоящее время для спецификации аппаратного обеспечения широко используются так называемые языки верификации аппаратуры (HVL, Hardware Verification Languages) [1]. К таким языкам относятся PSL, OpenVera, SystemVerilog и другие. HVL-языки включают в себя конструкции языков программирования, языков описания аппаратуры, а также специальные средства, ориентированные на верификацию. Средства спецификации, используемые в современных языках верификации аппаратуры, базируются на темпоральной логике линейного времени (LTL, Linear Temporal Logic) и темпоральной логике деревьев вычислений (CTL, Computation Tree Logic) [1]. Логика CTL используется преимущественно для формальной верификации систем. Для целей симуляции и тестирования больший интерес представляет логика линейного времени. Все языки, использующие LTL, имеют схожие средства спецификации. Они оперируют с ограниченными по времени последовательностями событий, для которых можно обращаться как к прошлому, так и к будущему. Из простых последовательностей можно строить более сложные с помощью логических связок, таких как И и ИЛИ, или используя регулярные выражения. На последовательностях событий можно с помощью темпоральных операторов задавать утверждения (assertions). В подходах на основе темпоральных логик, упор делается на временную декомпозицию операций. Для каждой операции сначала выделяется ее временная структура – допустимые последовательности событий и задержки между ними; затем определяются предикаты, описывающие отдельные события; после этого предикаты, относящиеся к одному моменту времени, могут быть некоторым образом сгруппированы. В подходе, предлагаемом нами, основной акцент ставится на функциональную декомпозицию операций. Первым делом выделяется функциональная структура операции в виде последовательности стадий; каждая стадия специфицируется; временная привязка спецификаций осуществляется в процессе тестирования с помощью вычисления на каждом такте условий блокировки стадий. Мы полагаем, что функциональная структура операции более устойчива по сравнению с временной. Тем самым, подходы, основанные на функциональной декомпозиции операций, позволяют разрабатывать спецификации более устойчивые к изменениям реализации по сравнению с подходами на основе темпоральных логик. К достоинствам предлагаемого метода можно отнести его наглядность. Контрактная спецификация конвейера базируется на известных разработчиками аппаратуры понятиях таких, как стадия операции, блокировка стадии и других. 124
5.2. Методы генерации тестовой последовательности Методы генерации тестов для аппаратуры с конвейерной организацией в основном исследуются в контексте тестирования микропроцессоров и их модулей. Многие исследователи сходятся во мнении, что удобным средством генерации тестовых последовательностей являются автоматные модели. Для построения тестов, покрывающих отдельные ситуации, часто используют методы проверки моделей [10-18]. Генерация тестов, полно покрывающих управляющую логику устройства, как правило, основана на обходе графа состояний автоматной модели [19, 20]. Автоматная модель либо извлекается автоматически на основе статического анализа кода реализации [19, 21], либо строится вручную [14, 20]. Автоматическое извлечение модели является сложной задачей, требующей либо наличия в коде аннотаций разработчиков [19], либо привлечения эвристик [10, 11]. Для сложного аппаратного обеспечения автоматическое извлечение автоматной модели управляющей логики практически неосуществимо. При построении модели вручную возникает другая проблема – построенную модель сложно отлаживать [20]. Поскольку на основе такой модели предполагается генерация тестов, важно, чтобы модель точно описывала тестируемый компонент, так как в противном случае цели тестирования не будут достигнуты. В предлагаемом методе автоматная модель управляющей логики извлекается из формальных спецификаций аппаратного обеспечения. Во-первых, это делает метод масштабируемым на достаточно сложные устройства (см. раздел 6). Во-вторых, это решает задачу отладки моделей, поскольку формальные спецификации, из которых извлекается автоматная модель, также используются для проверки правильности поведения.
6. Опыт практического применения метода Описанный в статье метод спецификации и тестирования аппаратуры с конвейерной организацией был применен для тестирования модулей промышленного микропроцессора с MIPS64-совместимой архитектурой [22]: буфера трансляции адресов (TLB, Translation Lookaside Buffer) и модуля кэшпамяти второго уровня (L2 cache). Для разработки тестов использовался инструмент CTESK из набора инструментов UniTESK [23], расширенный библиотекой PIPE, реализующей основные концепции предлагаемого подхода.
6.1. Тестирование буфера трансляции адресов Память тестируемого буфера трансляции адресов состоит из 64 ячеек, которые составляют объединенный TLB (JTLB, Joint TLB). Кроме того, для повышения производительности модуль содержит два дополнительных буфера из 4 ячеек каждый: TLB данных (DTLB, Data TLB) и TLB инструкций (ITLB, Instructions TLB). DTLB используется при трансляции адресов данных, ITLB – при трансляции адресов инструкций. Наличие двух дополнительных буферов 125
позволяет производить две операции трансляции адреса одновременно: одну для выборки инструкции (через ITLB), вторую для загрузки или сохранения данных (через DTLB). Модуль TLB реализует операции чтения, записи, проверки наличия ячейки в буфере, а также операции трансляции адресов данных и инструкций. Интерфейс модуля состоит из приблизительно 30 входов и стольких же выходов. Модуль реализован на языке Verilog, его описание (не считая библиотек) составляет около 3500 строк кода. Формальные спецификации и тесты были разработаны одним человеком приблизительно за 2.5 месяца, а их объем составил около 3500 строк кода. В результате тестирования было найдено 10 ошибок в реализации модуля, включая критичные. Найденные ошибки не были обнаружены при тестировании микропроцессора с помощью других методов7.
6.2. Тестирование модуля кэш-памяти второго уровня Тестируемый модуль кэш-памяти второго уровня имеет объем 256 Кбайт и состоит из 8192 строк. Каждая строка содержит данные (4 двойных слова по 64 бит), тэг (18 старших бит физического адреса) и биты служебной информации. Память модуля является смешанной – в ней могут храниться как данные, так и инструкции. Кэш-память адресуется физическим адресом путем прямого отображения. Модуль кэш-памяти реализует операции загрузки и сохранения данных (в разных режимах), выборки инструкций, а также управляющую операцию для изменения данных и управляющих битов. Интерфейс модуля содержит около 70 входов и 30 выходов. Реализация модуля на языке Verilog составляет около 3000 строк кода. Формальные спецификации и тесты были разработаны одним человеком приблизительно за 4 месяца, а их объем составил около 4000 строк кода. В результате тестирования были найдены 9 ошибок в реализации модуля.
7. Заключение В статье рассмотрен метод формальной спецификации аппаратуры с конвейерной организацией, основанный на пред- и постусловиях стадий выполнения операций. Метод позволяет в наглядной, интуитивно понятной форме описывать функциональность конвейерных устройств и может быть использован для функционального тестирования. Метод был успешно применен для проверки нескольких модулей промышленного микропроцессора. В результате тестирования были найдены серьезные ошибки, не обнаруженные при использовании других подходов. 7
Микропроцессор тестировался с помощью тестовых программ на языке ассемблера, разработанных вручную и полученных с помощью случайной генерации. 126
К настоящему моменту нами получен большой опыт использования технологии UniTESK и инструмента CTESK для спецификации и тестирования моделей аппаратуры [24]. Опыт показывает, что некоторые шаги разработки тестов могут быть полностью или частично автоматизированы [25]. Детальное исследование этого вопроса и разработка инструментальной поддержки для дальнейшей автоматизации разработки тестов является одним из приоритетных направлений дальнейшей работы. Еще одним направлением исследований является обобщение метода на более сложные типы конвейерных устройств. В работе был рассмотрен лишь простейший случай, когда последовательность стадий каждой операции фиксирована. На практике встречаются конвейеры с ветвлениями, в которых цепочки стадий вычисляются динамически на основе некоторых промежуточных условий, а также параллельные конвейеры, позволяющие запускать несколько операций параллельно. Литература [1] S.A. Edwards. Design and Verification Languages. Technical Report, Columbia University, New York, USA, November 2004. [2] B. Beizer. The Pentium Bug – An Industry Watershed. Testing Techniques Newsletter, TTN Online Edition, September 1995. [3] J. Bergeron. Writing Testbenches: Functional Verification of HDL Models. Kluwer Academic Publishers, 2000. [4] W. Lam. Hardware Design Verification: Simulation and Formal Method-Based Approaches. Prentice Hall, 2005. [5] D. Patterson and J. Henessy. Computer Organization and Design. 3rd Edition, Morgan Kaufmann, 2005. [6] А.В. Хорошилов. Спецификация и тестирование систем с асинхронным интерфейсом. Институт системного программирования РАН, Препринт 12, 2006. [7] И.Б. Бурдонов, А.С. Косачев, В.В. Кулямин. Использование конечных автоматов для тестирования программ. Программирование, 2000, №2. [8] И.Б. Бурдонов, А.С. Косачев, В.В. Кулямин. Неизбыточные алгоритмы обхода ориентированных графов. Детерминированный случай. Программирование, 2003, №5. [9] И.Б. Бурдонов, А.С. Косачев, В.В. Кулямин. Неизбыточные алгоритмы обхода ориентированных графов. Недетерминированный случай. Программирование, 2004, №1. [10] D. Moundanos, J. Abraham, and Y. Hoskote. A Unified Framework for Design Validation and Manufacturing Test. ITC'1996: International Test Conference, 1996. [11] D. Moundanos, J. Abraham, and Y. Hoskote. Abstraction Techniques for Validation Coverage Analysis and Test Generation. IEEE Transactions on Computers, Volume 47, 1998. [12] D. Geist, M. Farkas, A. Landver, Y. Lichtenstein, S. Ur, and Y. Wolfsthal. Coverage Directed Test Generation Using Symbolic Techniques. FMCAD'1996: Formal Methods in Computer Aided Design, 1996. [13] P. Mishra and N. Dutt. Automatic Functional Test Program Generation for Pipelined Processors using Model Checking. HLDVT'2002: High-Level Design Validation and Test Workshop, 2002.
127
[14] P. Mishra and N. Dutt. Architecture Description Language Driven Functional Test Program Generation for Microprocessors using SMV. CECS Technical Report 02-26, 2002. [15] P. Mishra and N. Dutt. Graph-Based Functional Test Program Generation for Pipelined Processors. DATE'2004: Design, Automation and Test in Europe Conference and Exhibition, 2004. [16] P. Mishra and N. Dutt. Functional Coverage Driven Test Generation for Validation of Pipelined Processors. DATE'2005: Design, Automation and Test in Europe Conference and Exhibition, 2005. [17] H.M. Koo and P. Mishra. Test Generation using SAT-based Bounded Model Checking for Validation of Pipelined Processors. ACM Great Lakes Symposium on VLSI, 2006. [18] H.M. Koo and P. Mishra. Functional Test Generation using Property Decomposition for Validation of Pipelined Processors. DATE'2006: Design, Automation and Test in Europe Conference and Exhibition, March 2006. [19] R. Ho, C. Yang, M. Horowitz, and D. Dill. Architecture Validation for Processors. ISCA'1995: International Symposium on Computer Architecture, 1995. [20] S. Ur and Y. Yadin. Micro Architecture Coverage Directed Generation of Test Programs. DAC'1999: Design and Automation Conference, 1999. [21] Y. Hoskote, D. Moundanos, and J. Abraham. Automatic Extraction of the Control Flow Machine and Application to Evaluating Coverage of Verification Vectors. ICCD'1995: International Conference of Computer Design, 1995. [22] MIPS64 Architecture For Programmers. Revision 2.0. MIPS Technologies Inc., 2003. [23] http://www.unitesk.com. [24] М. Chupilko, A. Kamkin, and D. Vorobyev. Methodology and Experience of Simulation-Based Verification of Microprocessor Units Based on Cycle-Accurate Contract Specifications. SYRCoSE'2008: The 2nd Spring Young Researchers Colloquium on Software Engineering, 2008. [25] В.П. Иванников, А.С. Камкин, В.В. Кулямин, А.К. Петренко. Применение технологии UniTESK для функционального тестирования моделей аппаратного обеспечения. Препринт 8. Институт системного программирования РАН, Москва, 2005.
128
Современная инфраструктура для обеспечения совместимости Linux-платформ и приложений В.В. Рубанов
[email protected] Аннотация. В статье описывается подход к построению инфраструктуры для эффективной разработки и использования спецификаций Linux-платформ. Подобные спецификации описывают программные интерфейсы (API) для обеспечения совместимости между различными реализациями таких платформ и различными приложениями для них. Задача рассматривается в условиях эволюционирующих версий спецификации платформы и наличия множественных платформенных реализаций и приложений, удовлетворяющих той или иной версии спецификации. Предлагаемый подход основан на использовании централизованной базы данных, содержащей структурированную информацию о различных версиях спецификации и различных реализациях платформ и приложений, а также средств автоматической верификации фактического соответствия реализаций платформ и приложений той или иной версии спецификации. Подход иллюстрируется на примере инфраструктуры для поддержки стандарта Linux Standard Base (LSB), основного промышленного стандарта на интерфейсы базовых библиотек операционной системы Linux.
1. Введение Одной из четко выделенных современных тенденций в мире разработки новых системных платформ можно с уверенностью назвать появление множества решений на базе операционной системы Linux. Новые платформы на базе этой ОС активно появляются в совершенно разных сегментах - от корпоративных серверов и рабочих станций до мобильных и встраиваемых систем. К сожалению, в условиях такого разнообразия системных платформ возникает проблема переносимости приложений между их различными реализациями. И если переносимость между различными сегментами (например, перенос приложения для мобильного телефона на сервер) не всегда востребована, то обеспечение совместимости различных платформ и приложений в рамках одного сегмента существенно необходимо как с точки зрения производителей платформ, так и с точки зрения производителей приложений и, в конце концов, с точки зрения конечных пользователей. 129
Это обусловлено тем, что проблемы переносимости приложений между разными платформами ограничивают число доступных приложений для каждой конкретной платформы, тем самым оказывая негативное влияние на сферу их применимости и, в конечном счете, популярность. С точки зрения разработчика приложений, проблемы переносимости увеличивают стоимость разработки, так как зачастую необходимо поддерживать различные версии приложения для каждой конкретной целевой платформы, или приводят к тому, что распространение приложения ограничивается одной частной платформой. Наконец, возможность использовать полный набор необходимых приложений на конкретной платформе или возможность смены платформы для предотвращения зависимости от поставщика (vendor lock-in) являются значимыми факторами для конечных пользователей, но именно эти возможности ставятся под угрозу из-за проблем переносимости приложений. Лучшее решение, которое было найдено на пути обеспечения переносимости приложений - это выработка открытых спецификаций (в том числе стандартов) программных интерфейсов, которые предоставляются платформой и на которые могут надежно опираться приложения. Такие спецификации описывают сигнатуры интерфейсов (имя функции, параметры, возвращаемые значения) и их поведение и являются своего рода публичным контрактом между производителями платформ и приложений. Корректные реализации программных интерфейсов платформы становятся совместимыми с приложениями, если последние соответственно ограничиваются использованием только специфицированных интерфейсов. Однако наличие только неформального описания в виде текста спецификации платформенных интерфейсов является недостаточным для эффективного использования такого подхода на практике. Как создатели платформенных спецификаций, так и разработчики соответствующих реализаций платформ и различных приложений для них нуждаются в инструментальной и методологической поддержке для успешного решения своих задач в практической плоскости. В данной статье рассматривается подход к организации такой поддержки на примере инфраструктуры, связанной с открытым стандартом на интерфейсы базовых библиотек операционной системы Linux - Linux Standard Base (LSB) [1]. Эта инфраструктура была построена в рамках совместной научноисследовательской и производственной деятельности ИСП РАН и Linux Foundation. Аналогичные инструменты и методы вполне применимы и для поддержки других системных платформ, в первую очередь основанных на Linux (например, Moblin [2], LiMo [3], Android [4], Maemo [5]). В первом разделе статьи дается обзор одной из наиболее успешных спецификаций программных интерфейсов, а именно стандарта Linux Standard Base (LSB). Второй раздел содержит описание современных достижений в области построения инфраструктуры поддержки интерфейсных стандартов на примере LSB. Среди подразделов выделяется историческая справка о 130
разработке инфраструктуры, а также отдельные подразделы, описывающие базу данных LSB, инструменты работы с ней, веб-портал разработчиков, сертификационные автоматизированные тесты и систему онлайн сертификации. В заключении приводится сводка результатов, полученных в ходе разработки инфраструктуры LSB, и делаются выводы.
2. LSB – спецификация единой платформы Linux Одним из наиболее ярких примеров спецификации Linux-платформ является стандарт Linux Standard Base (LSB) [1], основная идея которого заключается в описании общепринятого подмножества программных интерфейсов различных библиотек, составляющих «единую платформу Linux» с точки зрения производителей приложений. Это подмножество полностью представлено во всех основных дистрибутивах Linux в сегменте серверов и рабочих станций. Кроме собственно сигнатуры и поведения функций, спецификация интерфейсов в LSB включает также информацию бинарного уровня (в основном имена ELF-символов), необходимую для обеспечения переносимости приложений без перекомпиляции. Для разработки стандарта LSB в 2000 году был создан консорциум Free Standards Group (в настоящее время Linux Foundation [6]), который поддерживается ведущими ИТкомпаниями, такими как IBM, Intel, HP, Novell, Oracle и др. Первая версия стандарта была опубликована в июне 2001 года и описывала около 3000 интерфейсов. В последующие годы стандарт развивался и приобретал зрелость - в каждой версии появлялось все больше и больше интерфейсов (некоторые устаревшие исключались). Текущая версия LSB 3.2 включает более 30000 интерфейсов из более чем 40 библиотек. Большинство основных дистрибутивов Linux сертифицированы или фактически соответствуют этому стандарту (разные поколения дистрибутивов соответствуют разным версиям LSB). Важной особенностью стандарта LSB является то, что его разработчики не пытаются диктовать что-то новое для производителей дистрибутивов Linux. В большинстве случаев LSB просто ссылается на устоявшиеся промышленные стандарты и документацию, которым основные дистрибутивы удовлетворяют де-факто. Среди спецификаций, на которые ссылается LSB, стоит отметить Single Unix Specification (POSIX), ISO C99, ISO C++ Language и различную документацию разработчиков отдельных компонентов (как правильно библиотек) Linux. Только в случае отсутствия устоявшейся документации на тот или иной интерфейс LSB описывает его независимым образом, как правило, на основе анализа реализации интерфейса в основных дистрибутивах Linux. При принятии решений о стандартизации новых интерфейсов LSB использует критерии «наилучшей практики». Это означает, что интерфейс становится кандидатом для добавления в очередную версию LSB, если он присутствует в реализациях всех основных дистрибутивов Linux и этот интерфейс активно используется в приложениях. Другими словами, интерфейсы для 131
стандартизации должны быть достаточно популярны как среди разработчиков дистрибутивов, так и среди разработчиков приложений. Также, должны быть соблюден ряд технических требований, таких как наличие достаточно стабильных реализации, документации и тестов интерфейса. Важно отметить, что роль независящего от конкретного поставщика международного консорциума позволяет Linux Foundation принимать непредубежденные решения при разработке стандарта. Современная версия LSB 3.2 включает 5 обязательных модулей: • LSB Core – низкоуровневые системные интерфейсы C (библиотеки libc, libcrypt, libdl, libm, libpthread, librt, libutil, libpam, libz and libncurses). • LSB C++ - библиотека поддержки времени выполнения для языка C++ (libstdcxx). • LSB Desktop – различные функции для работы с графическим интерфейсом пользователя и вспомогательные сервисы (в основном XML, X11, GTK и Qt). • LSB Interpreted Languages – параметры окружения и стандартные модуля для языков Perl и Python. • LSB Printing – в основном библиотека libcups. Первые три модуля включают как архитектурно независимые описания, так и элементы, специфические для конкретных аппаратных архитектур, которые можно грубо представить в виде иерархии «модуль -> библиотека -> группа -> интерфейс». LSB 3.2 поддерживает 7 архитектур - IA32 (x86), AMD64 (x86_64), IA64 (Itanium), Power PC 32, Power PC 64, IBM S390 и IBM S390X. Модули Interpreted Languages и Printing включают только архитектурно независимые описания. Важно отметить, что LSB не нацелен на все дистрибутивы и приложения Linux – он лишь для наиболее распространенных решений общего назначения в сегменте серверов и рабочих станций. Специализированные дистрибутивы и некоторые системные приложения могут быть не вполне совместимы с LSB. Тем временем, даже если приложение использует некоторые интерфейсы за рамками LSB, то LSB все же имеет значение для таких приложений, так как позволяет сократить издержки на обеспечение переносимости в области интерфейсов, пересекающихся с LSB, на которые приложение может надежно опираться. Для обеспечения совместимости для интерфейсов вне LSB можно использовать отдельные методы, такие как статическая линковка необходимых библиотек или разработка специальных библиотекпереходников, которые могут скрывать различия между различными дистрибутивами для заранее заданного набора необходимых интерфейсов. LSB позволяет сократить число интерфейсов, для которых нужно применять такие специальные (относительно дорогостоящие) меры.
132
3. Техническая инфраструктура поддержки LSB
3.2. База данных LSB
Важнейшим фактором для эффективной разработки и поддержки интерфейсных спецификаций (в том числе стандартов) для системных платформ является техническая инфраструктура, обеспечивающая автоматизацию ключевых процессов в работе над спецификацией и облегчающая ее использование разработчиками. На примере LSB в качестве основных компонентов инфраструктуры поддержки можно назвать генераторы текста стандарта на основе центральной базы данных, веб-портал для разработчиков, системы анализа и принятия решений по развитию стандарта, тесты реализаций платформ (дистрибутивов) и приложений, включая системы автоматизированного запуска тестов, анализа результатов и сертификации. В последующих разделах дается подробный обзор этих элементов инфраструктуры после небольшого исторического отступления, описывающего историю разработки инфраструктуры LSB.
Основой инфраструктуры поддержки стандарта LSB является централизованная база данных (используется СУБД MySQL), которая содержит интегрированную информацию о структуре стандартизованных элементов (от модулей до конкретных интерфейсов, их параметров, типов данных, виртуальных таблиц, и т.п.). Также эта база данных включает информацию о составе существующих дистрибутивов Linux и внешних зависимостях различных популярных приложений. Кроме того, в базе данных отражается различная оперативная информация (например, статус сертификации различных продуктов, в том числе промежуточный). Текущая база в общей сложности содержит 92 таблицы с более чем 65 миллионами записей, которые можно условно разделить на три части: 1. Часть поддержки стандартизации – включает информацию о стандартизованных элементах LSB и об элементах-кандидатах. 2. Экосистемная часть – содержит информацию о составе (предоставляемые библиотеки и интерфейсы) основных дистрибутивов и зависимостях (требуемые от дистрибутива библиотеки и интерфейсы) популярных приложений. 3. Сертификационная часть – содержит оперативную информацию о статусе сертификации различных продуктов (дистрибутивов и приложений), об операциях аудита, о платежах за процедуру официальной сертификации и т.п.
3.1. Проектная программа LSB Infrastructure Российские специалисты активно вовлечены в LSB сообщество. Первым крупным проектом в этом направлении был Open Linux VERification (OLVER) [7]. Проект выполнялся Центром верификации ОС Linux [8] при Институте системного программирования РАН [9] по заказу Федерального агентства по науке и инновациям (Роснаука). В проекте был проанализирован текст основной (core) части стандарта LSB для около 1500 системных функций Linux, были формализованы требования на поведение этих функций и построены тесты для автоматической проверки дистрибутивов Linux на соответствие этим требованиям [10]-[11]. Результаты проекта OLVER заинтересовали комитет по стандартизации LSB в тот момент консорциум Free Standards Group (FSG), который предложил ИСП РАН долгосрочное сотрудничество в области построения новой инфраструктуры использования и развития стандарта LSB, а также разработки технологий автоматизации тестирования и создания собственно новых тестов для Linux, что являлось основным больным местом, сдерживающим дальнейшее развитие и продвижение этого стандарта. Впоследствии, в результате слияния FSG с OSDL был создан консорциум Linux Foundation [6] и сотрудничество с ИСП РАН было расширено. Важно отметить, что все результаты работ Linux Foundation и ИСП РАН в рамках этого сотрудничества являются открытыми и свободными (opensource) для сообщества разработчиков Linux. Первые результаты по созданию новой инфраструктуры в рамках проектной программы LSB Infrastructure [12] были представлены в июне 2007 года на конференции Linux Foundation Collaboration Summit 2007 и с тех пор они постоянно развиваются с помощью системы выпуска регулярных версий. Далее рассматривается текущее (конец 2008 года) состояние инфраструктуры LSB. 133
Часть поддержки стандартизации описывает следующие элементы: • группирующие элементы: o модули (наборы библиотек и команд); o библиотеки (наборы интерфейсных групп и заголовочных файлов); o интерфейсные группы (наборы классов и интерфейсов); o заголовочные файлы (наборы интерфейсов, типов данных и констант); • основные элементы: o команды (например, ls, cat и т.п.); o классы C++; o интерфейсы (включая глобальные переменные); o константы и макросы; o типы данных. Все эти элементы связаны в граф зависимостей различных видов так, что имеющейся информации достаточно для полностью автоматической генерации заголовочных файлов, которые содержат декларации всех необходимых элементов, входящих в стандарт. Идея экосистемной части заключается в объединении в одном месте информации о составе (предоставляемые библиотеки и интерфейсы) основных дистрибутивов и зависимостях (требуемые от дистрибутива библиотеки и интерфейсы) популярных приложений. Эта информация постоянно 134
обновляется и позволяет анализировать текущее положение с точки зрения принятия решений о развитии стандарта. Например, вот основные вопросы, на которые становится возможным ответить: какими дистрибутивами предоставляется (или наоборот в каких отсутствует) тот или иной интерфейс или насколько этот интерфейс популярен среди производителей приложений? Сертификационная часть поддерживает процесс сертификации, в том числе содержит официальный реестр сертифицированных продуктов, удовлетворяющих той или иной версии LSB. Также данные в этой части используются для оперативной работы онлайн системы сертификации LSB Certification System.
• • • •
3.3. Инструменты работы с БД и веб-портал разработчиков База данных LSB используется различными инструментами, среди которых стоит отметить более 40 скриптов, которые генерируют различные части «технического пакета поддержки LSB», такие как части текста самой спецификации стандарта, заголовочные файлы, части реализации инструментов тестирования и разработки (Software Development Kit - SDK). Для эффективного использования данных из БД человеком был создан вебпортал LSB Navigator, который предоставляет графический интерфейс пользователя и позволяет эффективно работать с данными в базе данных, включая поиск, рубрикатор, кросс-ссылки, возможности обратной связи и т.п. Этот портал находится в публичном доступе (http://linuxfoundation.org/navigator/) и предназначен как для рабочей группы по стандартизации LSB, так и для разработчиков различных дистрибутивов и приложений Linux. Основные возможности LSB Navigator включают: • Навигацию по стандартизованным элементам LSB от модулей до конечных элементов в виде интерфейсов, типов данных, констант и т.п. • Глобальные фильтры по версии LSB и по аппаратной архитектуре. • Индивидуальные «домашние странички» для более миллиона интерфейсов Linux (доступных всего в 2 перехода с главной страницы с помощью специализированного поиска), которые в свою очередь содержат следующую информацию: o LSB статус интерфейса («включен в LSB», «никогда не был в LSB», «планируется для включения», «был исключен», «будет скоро исключен» - deprecated); o контекст интерфейса (модуль, библиотека, заголовочный файл, к которым относится интерфейс и т.п.); o сигнатура интерфейса (имя, параметры и возвращаемое значение); o прямая ссылка на описание (в первую очередь поведения) интерфейса; o список дистрибутивов, которые предоставляют этот интерфейс; 135
o список приложений, которые используют этот интерфейс; o список открытых тестов, которые проверяют этот интерфейс; o обсуждения сообщества, связанные с этим интерфейсом. Информацию о дистрибутивах (предоставляемые библиотеки и интерфейсы). Информацию о приложениях (внешние зависимости по библиотекам и интерфейсам). Статистику по LSB элементам (общее число интерфейсов, команд, классов и т.д. в каждой версии LSB). Статистику по использованию интерфейсов приложениями: o Какие интерфейсы и библиотеки наиболее часто используются приложениями; o «LSB рейтинг» приложений – список приложений с указанием числа LSB и не-LSB библиотек и интерфейсов, используемых каждым приложением.
LSB Navigator фактически представляет собой интерактивную версию стандарта LSB и базу знаний с различной дополнительной информацией (аналогично Microsoft MSDN). Другие системы могут легко ссылаться на странички внутри LSB Navigator, позволяя интегрировано предоставлять пользователям контекстную информацию.
3.4. Сертификационные тесты дистрибутивов Ian Murdock, бывший руководитель рабочей группы LSB и технический директор Free Standard Group, а в настоящее время директор по операционным системам в Sun Microsystems, говорил: “Интерфейсный стандарт хорош настолько, насколько хороши автоматизированные тесты, проверяющие соответствие стандарту». Тогда он имел в виду тесты, проверяющие корректность реализации интерфейса в платформе (дистрибутивах в случае Linux), однако стоит отметить, что важны также и тесты приложений, которые проверяют, что приложения используют только стандартизованные интерфейсы и делают это корректным образом. Тем не менее, далее речь будет идти в основном о тестах дистрибутивов. В конце 2006 года покрытие LSB интерфейсов тестами составляло около 15%, что означало, что 85% стандартизованных тестов вообще не имели тестов. Именно поэтому разработка новых автоматизированных тестов соответствия дистрибутивов требованиям стандарта является важнейшим приоритетом программы LSB Infrastructure. Однако проблема заключалась в том, что стандарт включает огромное количество интерфейсов и создать за разумное время необходимое количество по-настоящему мощных тестов не представлялось возможным. В то время как было неприемлемым и то, что некоторые интерфейсы вообще не имели каких-либо тестов. Для решения этих проблем в условиях ограничений на ресурсы специалистами ИСП РАН была 136
предложена стратегия, основанная на выделении трех уровней качества тестов. 1. Глубокие (Deep) – на этом уровне целевой интерфейс вызывается много раз (в среднем около 100) в различных ситуациях (с различными параметрами и в различных внутренних состояниях). 2. Средние (Normal) – это наиболее распространенный уровень качества тестирования, принятый в индустрии. Целевой интерфейс проверяется в нескольких (в среднем 5) основных ситуациях. 3. Поверхностные (Shallow) – простейшие тесты с единственной гарантированной целью – вызвать целевой интерфейс хотя бы один раз в какой-нибудь типичной ситуации и проверить, что не было аварийного сбоя (crash). Этот уровень близок к понятию тестов существования или санитарных тестов (“existence”, “smoke”, “sanity”). Согласно предложенной стратегии, все интерфейсы, не имеющие тестов, были проанализированы и разбиты на три группы по степени важности интерфейса. Соответственно для особо важных интерфейсов было предложено разрабатывать глубокие тесты, для основной массы библиотек - тесты среднего уровня, а для многочисленных, но не важных, интерфейсов разработать поверхностные тесты. Для автоматизации разработки тестов различных уровней было предложено соответственно три технологии (включая соответствующие инструменты поддержки). 1. UniTESK (см. [13]) – для разработки глубоких тестов. 2. T2C (см. [14]) – для разработки тестов среднего уровня. 3. AZOV (см. [15]) – для разработки поверхностных тестов. В таблице 1 приведены данные о разработанных сотрудниками ИСП РАН новых тестах различного уровня. Трудоемкость разработки дана интегрально для полного цикла от изучения целевой системы до разработки и отладки теста на многочисленных системах и аппаратных архитектурах с последующим анализом/исправлением находимых проблем. Уровень тестов Глубокие Средние Поверхностные
Кол-во тестируемых интерфейсов 1 500 3 700 21 800
Кол-во Среднее кол-во Трудоемкость тестовых испытаний на разработки (чел.испытаний 1 интерфейс дней/интерфейс) ~150 000 100 5 17 200 5 1 21 800 1 0,02
Таблица 1. Статистика по разработанным в ИСП РАН новым тестам для LSB.
137
Важно отметить, что поверхностные тесты отличаются от глубоких и средних не только малым количеством тестовых испытаний, но и почти полным отсутствием проверок корректности функциональности. Глубокие и средние тесты содержат систематически выделенные согласно разработанной методологии проверки каждого атомарного требования из текста стандарта. При этом, когда разработанные таким образом тесты обнаруживают ошибку, то выводится не только обычная диагностика о параметрах конкретного несоответствия (например, «ожидалось XX, но функция вернула YY»), но и сообщается ссылка на конкретное место в тексте стандарта, в котором описано нарушенное общее требование. Такой уровень диагностики существенно облегчает процесс реального тестирования и повышает комфорт пользователей с точки зрения тестирования соответствия стандарту. Согласно принятой стратегии полное покрытие всех LSB интерфейсов тестами ожидается закончить к концу 2009 года.
3.5. Средства автоматизации LSB-сертификации Для того чтобы тесты соответствия можно было эффективно использовать на практике, нужны не только сами тесты (каждый из которых грубо представляет собой отдельную программу), но и средства их автоматизированного запуска и анализа результатов. Кроме того, необходима информационная система, которая поддерживает рабочие процедуры (workflow) формальной сертификации на основе результатов тестирования. В рамках программы LSB Infrastructure в начале 2008 года была разработана онлайн система поддержки LSB сертификации (LSB Certification System), которая направляет пользователей через необходимые шаги для выполнения тестирования их продуктов, разрешения проблем и в конечном итоге получения формальной сертификации. Эта система включает 3 основные части: • Управление сертификацией (Certification Workflow Management) – предоставляет пошаговые инструкции с хранением текущего индивидуального статуса (шаги могут быть произвольно разнесены по времени) для проведения сертификации дистрибутивов и приложений на соответствие LSB. • Реестр сертифицированных продуктов (LSB Product Directory) – публичная часть сертификационной системы, которая хранит список сертифицированных LSB продуктов, обеспечивая различные интерактивные группировки и фильтры при просмотре. • Подсистема управления проблемами (Problem Reporting) – предназначена для онлайн поддержки в разрешении различных проблем, которые возникают в процессе сертификации, например, пользователи могут сталкиваться с ошибками в тестах, и необходимо исследовать такие случаи и игнорировать такие ошибки при рассмотрении результатов тестирования. Фактически эта подсистема представляет систему 138
управления публичной базой знаний, одновременно предоставляя возможность организованного индивидуального общения между пользователями и сотрудниками рабочей группы LSB. Соответственно, в системе присутствуют два режима – для пользователей и для сотрудников рабочей группы LSB (администраторов). Наконец, в основе технической части процесса сертификации лежит запуск автоматизированных тестов соответствия и анализ их результатов. Для этих целей были разработаны инструменты Distribution Testkit Manager и Linux Application Checker для тестирования соответственно дистрибутивов и приложений. Эти средства представляют собой программные комплексы автоматизации и управления тестированием, которые обеспечивают следующие основные возможности: • интегрированный интерфейс пользователя (графический и командной строки на выбор), одинаковый для всех тестовых наборов LSB (созданных по различным технологиям); • выбор, какие именно тесты запускать (все, заранее определенные поднаборы или вручную выбранное подмножество); • сохранение всех настроек конфигурации для обеспечения непрерывности процесса тестирования в различных сеансах работы; • автоматическая загрузка недостающих на локальном компьютере тестов с FTP-сайта Linux Foundation; • запуск сертификационных тестов «одной кнопкой»; • унифицированные интерактивные отчеты о результатах тестирования, интегрированные с базой знаний известных ошибок и дополнительных рекомендаций, а также с контекстными ссылками на странички в LSB Navigator. Это позволяет пользователям тестов эффективно анализировать результаты тестирования; • реестр истории запусков с возможностью регрессионного сравнения. Онлайн система LSB сертификации и инструменты автоматизации запуска тестов интегрированы друг с другом, обеспечивая прозрачные переходы между локальной и серверной функциональностью для облегчения процесса сертификации в целом от организационных аспектов до технических.
4. Заключение Проблемы переносимости приложений между различными реализациями системных платформ создают трудности, как разработчикам самих платформ, так и разработчикам приложений и конечным пользователям. Именно эти проблемы являются огромным негативным фактором для успеха той или иной платформы. В мире Linux, где число различных реализаций платформ исчисляется сотнями, вопросы совместимости приобретают критическое значение. 139
Основной инициативой по обеспечению переносимости приложений между различными Linux-платформами в сегменте серверов и рабочих станций является стандарт Linux Standard Base. Опираясь в частности на один из старейших интерфейсных стандартов POSIX, LSB является наиболее зрелым примером спецификации системной платформы и набора технических и организационных решений, составляющих инфраструктуру поддержки ее эффективной эволюционной разработки и использования. В данной статье были рассмотрены основные компоненты этой инфраструктуры, такие как: • централизованная база данных, содержащая структурированную информацию о стандартизируемых элементах и окружающей их экосистеме; • инструменты автоматической генерации отдельных элементов текста спецификации и реализаций инструментов и тестов для разработчиков приложений на основе базы данных; • веб-портал для эффективного представления информации в базе данных (интерактивная версия спецификации и база знаний); • тесты для проверки реализаций платформ на соответствие спецификации; • тесты для проверки приложений на предмет корректного использования специфицированных интерфейсов платформы; • инструменты автоматизации запуска тестов и анализа результатов тестирования; • интегрированная с вышеуказанными инструментами онлайн система сертификации продуктов (реализаций платформ и приложений). Эта инфраструктура была построена коллективом Центра верификации ОС Linux при Институте системного программирования РАН в рамках сотрудничества с международным консорциумом Linux Foundation. Разработанные средства успешно применяются на практике и получили массу положительных отзывов, как от разработчиков самого стандарта, так и от разработчиков различных дистрибутивов и от разработчиков Linuxприложений. Есть все основания, что построение аналогичной инфраструктуры будет чрезвычайно полезно и для других спецификаций системных платформ, в первую очередь основанных на Linux (например, Moblin, LiMo, Android или Maemo), особенно там, где существуют множественные реализации платформы, а сама спецификация платформы постоянно эволюционирует. Литература [1] [2] [3] [4] [5] [6]
140
Linux Standard Base Homepage. http://www.linuxfoundation.org/en/LSB/. Moblin Homepage. http://moblin.org/ LiMo Homepage. http://www.limofoundation.org/ Android Homepage. http://code.google.com/intl/ru/android/ Maemo Homepage. http://maemo.org/ Linux Foundation. http://linuxfoundation.org/
[7] [8] [9] [10] [11]
[12] [13] [14] [15]
Проект Open Linux VERification (OLVER). http://linuxtesting.org/project/olver Linux Verification Center. http://linuxtesting.org Institute for System Programming of the Russian Academy of Sciences. http://ispras.ru/ V. Kuliamin, A. Petrenko, V. Rubanov, A. Khoroshilov. Formalization of Interface Standards and Automatic Construction of Conformance Tests. Proceedings of SECR 2006 conference, Moscow. А. И. Гриневич, В. В. Кулямин, Д. А. Марковцев, А. К. Петренко, В. В. Рубанов, А. В. Хорошилов Использование формальных методов для обеспечения соблюдения программных стандартов. Труды ИСП РАН, том.10, , 2006. С.51-68. LSB Infrastructure Program. http://ispras.linuxfoundation.org http://www.unitesk.com В.В.Рубанов, А.В.Хорошилов, Е.А.Шатохин. T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов. Труды ИСП РАН: Том 14, часть 2, 2008. С.65-82. Р. С. Зыбин, В. В. Кулямин, А. В. Пономаренко, В. В. Рубанов, Е. С. Чернов. Технология Azov автоматизации массового создания тестов работоспособности. Труды ИСП РАН, том. 14, часть 2:83-108, 2008.
141
Ориентированные на приложения методы хранения XML-данных Максим Гринев, Иван Щеклеин
[email protected],
[email protected] 1. Введение Модель данных XQuery [1] является стандартной моделью данных для работы со слабоструктурированными данными, представленными в формате XML. Поддержка слабоструктурированных данных делает эту модель достаточно универсальной и пригодной для преставления данных различной степени структурированности от регулярных реляционных данных до текстовых документов с размытой структурой. Оборотной стороной такой универсальности является достаточно низкая эффективность существующих реализаций. На сегодняшний день уже сложился ряд подходов [2, 3, 4, 5] к реализации модели данных, но каждый из этих подходов обладает очевидными преимуществами и недостатками, что делает эти подходы применимыми только для достаточно узких классов приложений. Более того, модель данных XQuery поддерживает возможности, которые являются избыточными для каждого конкретного вида приложения. Например, предположим, что приложение использует XML для представления реляционных данных. Запросы к таким данным обычно не требуют поддержки таких возможностей модели данных как братские (sibling) и родительские (parent) оси или порядок узлов в документе (document order). Другой пример – это запросы к контент-ориентированным XML-данным, таким как энциклопедические статьи [7] или текстовый документ, представленный в формате Microsoft Word XML [6]. Зачастую такие запросы не адресуют XML-элементы, предназначенные для описания способов визуализации данных (примеры такие элементов: para, bold, emphasize и другие, которые составляют, как правило, большую часть элементов в документе), но адресуют семантически значимые элементы, такие как author, дата, библиография. Следовательно, элементы визуализации могут быть представлены на уровне хранения в сжатом незапрашиваемом виде для увеличения скорости операций модификации и сериализации XML данных (под сериализацией здесь и далее мы понимаем процесс трансляции 143
внутреннего представления данных в строковое представление, соответствующее формату XML). Приведенные выше рассуждения позволяют нам прийти к выводу, что эффективное внутреннее представление и обработка XML-данных не могут быть достигнуты с использованием какого-либо общего подхода. По нашему мнению, единственно возможным подходом, способным обеспечить высокую эффективность для такой универсальной модели данных, является выбор способов внутреннего представления и методов обработки данных под потребности конкретного приложения. При этом достаточной информацией для описания потребностей является схема XML-данных и рабочая нагрузка в виде возможных запросов и операций модификации данных. То есть мы предлагаем пойти дальше построения планов выполнения запросов при фиксированных структурах хранения данных, как это делается в большинстве современных систем управления XML-данными, и, кроме того, выбирать структуры хранения данных, необходимые для эффективного выполнения запросов и модификаций для данного приложения. Такой подход позволит поддерживать XQuery модель данных на логическом уровне, но избежать излишних накладных расходов на физическом уровне хранения данных. С использованием такого подхода можно добиться эффективности обработки регулярных реляционных данных в формате XML, сопоставимой с эффективностью, которая обеспечивается реляционными базами данных. При этом контент-ориентированные данные будут обрабатываться с эффективностью, сопоставимой с эффективностью систем хранения текстовых документов. В данной статье мы описываем наши первые результаты по разработки таких методов хранения и обработки XML-данных. Статья имеет следующую структуру. В следующем разделе мы рассматриваем примеры, демонстрирующие преимущества предлагаемого подхода. В разд. 3 дается обзорное описание подхода. В разд. 4 описывается физическое представление данных и иллюстрируется на примерах. Разд. 5 посвящен обзору близких работ и существующих подходов хранения XML-данных. В заключительном, шестом разделе мы намечаем пути дальнейших исследований.
2. Мотивирующие примеры Для демонстрации основных преимуществ и различных аспектов предлагаемого подхода мы выбрали упрощенную версию приложения, которое используется для создания электронной версии Большой Российской Энциклопедии (БРЭ) [7]. Иллюстрации 1 и 2 показывают фрагменты XMLдокумента, содержащего статью энциклопедии, и его описывающей схемы соответственно. По определению [9] описывающая схема содержит ровно 144
один путь для каждого пути в документе, и каждый путь в описывающей схеме является путем хотя бы в одном из документов. В этом примере документ представляет собой том энциклопедии, который содержит, по крайней мере, три статьи. Каждая статья состоит из заголовка, списка авторов и тела, которое содержит текст статьи. <article id="2"> Cyclotron resonance Century S.Edelman. I. Kaganov
Cyclotron resonance Selective absorption electromagnetic... Effective weight
... ... ... ... ...
Lorentz force... ... <article id="3"> Dorfman Jacob Grigorevich I. Ivanov
Dorfman Jacob Grigorevich the Soviet physicist, doctor... Cyclotron resonance ... ... ...
... <article id="1"> Effective weight I. Kaganov ...
element volume
element article
attribute id
element authors
element title
element body Content Markup
text
of
element author
text
text p
element link
...
b
element i ... span
element link
attribute idref
attribute idref
text
text
Рис. 2. Описывающая схема Большой Российской Энциклопедии
the
Для обработки энциклопедии в приложении используются набор запросов, которые являются предопределенными и могут изменяться только при переходе к новой версии системы. Ниже приводится список основных запросов. (Q1) Получение списка названий статей declare ordering unordered; volume/article/title
(Q2) Получение статьи по идентификатору declare ordering unordered; volume/article[@id eq “...”]
Рис. 1. Фрагмент Большой Российской Энциклопедии.
(Q3) Получение статьи по названию declare ordering unordered; volume/article[title eq “...”]
145
146
(Q4) Перечислить названия статьей, на которые ссылается статья с идентификатором равным 1 declare ordering unordered; for $i in volume/article [@id eq “1”]//link return volume/article [@id eq $i/@idref]/title
(Q5) Перечислить звания статей, которые ссылаются на статью с названием «Атом» declare ordering unordered; let $j := volume/article [title eq “atom”]/@id for $i in volume/article where $i//link[@idref eq $j] return $i/title
Рассматривая этот пример, мы можем выделить несколько интересных моментов, которые являются общими для многих приложений. 1. Элементы визуализации. Контент-ориентированные XML документы часто содержат большое количество XML-элементов, которые обрабатываются исключительно front-end-приложениями (такими как браузер или текстовый процессор) при отображении документа. В приведенном выше примере к таким элементам относятся p, i, b. Такие элементы, как правило, не адресуются запросами. Однако при хранении XML-документов с использование любого общего подхода такие элементы будут представляться таким же образом, как и семантически значимые элементы. 2. Реляционные данные. Помимо элементов визуализации в приведенном примере можно выделить элементы и атрибуты с простыми значениями (например, атрибуты id, idef и title element), которые адресуются запросами. При этом значения этих элементов и атрибутов используются только как промежуточные данные при вычислении запросов в том смысле, что это эти элементы не извлекаются сами по себе, а только как часть другого элемента (например, атрибут id используется для нахождения статьи и извлекается из базы данных только как часть статьи). 3. Порядок узлов документа (document order). По умолчанию результат вычисления запроса неявно сортируется в порядке узлов в документе. Однако очень часто этот порядок не имеет никакого значения для приложения. Например, в рассматриваемом примере не имеет смысла взаимный порядок следования названия статьи и авторов. В приведенных запросах неявная сортировка выключается в прологе. 4. Известные наперед запросы (рабочая нагрузка). В приведенном приложении все запросы известны еще на этапе его создания, то есть система не поддерживает ad hoc запросов к данным. Это позволяет нам, в 147
частности, построить список путевых выражений, которые составляют основу всех этих запросов: volume/article, volume/article/link, volume/article/title. Далее в статье мы покажем, как приведенные выше соображения могут быть использованы для выбора структур хранения и планов выполнения запросов.
3. Описание подхода Для реализации предлагаемого подхода необходимо решить две основные задачи: разработать методы выбора структур хранения для наперед известной и неизменной рабочей нагрузки; разработать методы реорганизации структур хранения на случай изменения рабочей нагрузки. Как мы уже отмечали выше, предполагается, что для большинства приложений рабочая нагрузка (то есть запросы и операции модификации) известна заранее и не подвержена частым изменениям. В следующих подразделах мы рассматриваем каждый из этих методов.
Рис. 3. Различные способы представления данных
3.1. Выбор структур приложение
хранения
ориентированных
на
Имея заранее известную рабочую нагрузку, мы компилируем планы выполнения запросов и соответствующий план хранения данных для заданной нагрузки. В этих планах возможности языка XQuery, которые являются избыточными для поддержки требуемых запросов, не поддерживаются при выполнении. Для построения плана хранения мы используем следующие основные методы: 1) Комбинирование структурного и текстового представления данных. Как уже упоминалось выше, большинство элементов в контенториентированных XML документах никогда не адресуются запросами. Нами был разработан метод анализа запросов, позволяющий выявить узлы документов, которые необходимо хранить в структурном 148
представлении (т.е. поддерживая необходимые указатели для навигации между узлами документов) для возможности вычислить все запросы эффективным способом. Все остальные элементы (как правило, это элементы визуализации) сохраняются в текстовом представлении в виде текстовых узлов XML модели данных. Разработанный метод является достаточно гибким и не ограничивается сохранением всего XML поддерева в виде текста. Элементы со структурным представлением могут иметь в качестве детей элементы с текстовым представлением, которые в свою очередь содержат в качестве детей элементы со структурным представлением. Мы также расширили этот подход для хранения в текстовом представлении некоторых элементов, адресуемых запросом, но по которым не производится поиск. Например, рассмотрим запрос «найти имена все сотрудников старше 60 лет». В этом запросе поиск производится по элементу «возраст» и этот элемент имеет смысл хранить в структурном виде. В то же время элемент «имя» можно хранить в текстовом виде как часть элемента «сотрудник», поскольку предполагается, что в результате поиска обычно возвращается небольшое число элементов, и для них извлечение имени из текстового представления через разбор на лету не является дорогостоящей операцией для всех найденных сотрудников. Для эффективного разбора на лету предлагается использовать методы потоковой обработки XML [18]. 2) Комбинирование методов кластеризации узлов в блоках внешней памяти. Кластеризация по описывающей схеме, используемая в Sedna XML Database [9], может быть использована совместно с методом хранения рядом детей и родителей, который используется в системах Natix и DB2 [2, 3]. Выбор способа кластеризации для различных групп узлов производится на основе анализа запросов. Комбинирование этих двух методов должно дать существенный выигрыш в производительности. 3) Исключение избыточных структур и выравнивание вложенности. Анализируя запросы, можно установить, какие структуры являются избыточными для их выполнения. Главным образом, можно удалять излишние указатели и группирующие элементы. Например, реляционные XML-данные могут быть сохранены в виде компактных записей близко к тому, как они хранятся в реляционных системах. Такие записи не имеют такую же строгую структуру, как в реляционных системах, поскольку необходимо поддерживать возможность нерегулярности в данных, но группировка элементов в записи существенно повышает эффективность системы, так как сокращается количество блоков, которые необходимо прочитать. Подобное «уплощение» данных можно проводить и в ряде других случаев для исключения промежуточных элементов. Например, если элемент «сотрудник» содержит элемент «адрес», содержащий, в свою очередь, элементы «улицы» и «дом», то элемент адрес может быть исключен, если 149
на его уровне нет элементов с именем «улицы» и «дом», которые могут значить что-либо другое. Обратим внимание, что метод не приводит к потере или размножению данных, а только исключает излишние структурные элементы, однако он может быть естественным образом расширен использованием проекции данных выполняемой при загрузке или модификации данных или поддержкой материализованных представлений. Проекции могут быть построены по анализу путевых выражений или предикатов с константами. Кроме того, исключение избыточных структур (особенно указателей) имеет еще и потенциальное преимущество, связанное с тем, что узлы становятся менее связанными, что не только повышает скорость выполнения запросов и модификаций, но и открывает новые перспективы в улучшении гранулярности транзакционных блокировок и построении распределенных баз данных. Например, это создает предпосылки для реализации параллелизма по данным (data parallelism) на архитектуре shared-nothing.
3.2. Реорганизация приложения
структур
хранения
при
изменении
В случае изменения приложения (то есть изменения рабочей нагрузки) в общем случае необходимо полностью перестраивать хранимые данные с целью изменения структуры их хранения. При этом политика реорганизации может быть достаточно гибкой. Во-первых, частота, с которой производится реорганизация, может быть сделан зависимой от выбранного уровня оптимизации, который задается в приложении. Во-вторых, реорганизация будет требоваться не так часто, как это может показаться на первый взгляд. В самом деле, мало вероятно, что новые запросы, которые обращены к «реляционным» XML-данным начнут использовать ссылки на братьев (sibling pointers), которые были удалены на этапе компиляции плана хранения. Тем не менее, в общем случае реорганизация все равно может потребоваться. Реорганизация может проводиться следующим образом. Вся база данных целиком может быть перестроена с использование массивно-параллельных распределенных вычислений. На современном оборудовании такое перестроение базы данных небольшого и даже среднего объема может быть осуществлено за приемлемое время, равное одному прочтению базы данных с диска. Как отмечалось выше, «уплощение» структур хранения облегчает создание распределенных баз данных. Если база данных является распределенной, то такая перестройка может быть произведена еще быстрее. В простом случае (когда не были использованы методы оптимизации распределенных баз данных, например, collocated join [10]) перестройка может быть выполнена параллельно и независимо для каждого узла распределенной базы данных. В более сложном случае (данные распределены по узлам для возможности 150
использовать collocated join) могут быть применены методы, подобные mapreduce [11], для перераспределения данных. При реорганизации базы данных существует две основные альтернативы. Вопервых, простое решение состоит в остановке базы данных на время перестройки. Если предположить, что для малых и средних баз данных перестройка не займет много времени, то такое решение приемлемо для многих приложений и может осуществляться в ночное время. Более продвинутое решение состоит в использовании механизма теневых страниц (или snapshot isolation [12]) для реорганизации базы данных без ее остановки.
сэкономить место и увеличить скорость сериализации. Как упоминалось в разд. 3, этот подход не исключает полностью возможность запрашивать элементы из текстового представления, поскольку может быть использован механизм разбора текстового представления на лету. Тестовое представление может содержать заглушки (placeholders) для ссылок на узлы, сохраненные с использование двух приведенных выше методов.
4. Представление данных физического уровня В этом разделе мы даем обзор основных идей для создания перестраиваемого внутреннего представления XML-данных, оптимизированного под заданную рабочую нагрузку. Вернемся к примеру, приведенному в разд. 2. Описывающая схема используется для группировки XML-узлов по путям в документе. Для каждой группы узлов оптимальный способ хранения выбирается с учетом нагрузки (рис. 3, a-c): • Дискриптор узла (node descriptor). Каждый узел в группе может быть сохранен как дескриптор узла, который имеет прямые указатели на детей, родителей и братьев. Это дает возможность эффективной навигации для вычисления структурных путевых выражений [9]. Кроме того, в этом подходе может быть использована нумерующая схема [11, 9]. Каждый дескриптор узла содержит метку номерующей схемы (nid). Основное преимущество использования нумерующей схемы состоит в быстром определении связей предок-потомок между любой парой узлов. Нумерующая схема может быть также использована для определения связей, заданных порядком узлов в документе (document order relationship). • Значения, упакованные в дескриптор узла. Для некоторых узлов могут быть использованы структуры, схожие с записями, используемыми при хранении реляционных данных [20]. Запись упаковывается в дескриптор узла (как значения id и title, показанные на рисунке 3, b). Такое “уплощение” данных дает несколько преимуществ. Во-первых, мы получаем практически максимально компактное представление за счет избавления от лишних указателей. Во-вторых, ускоряется выполнение путевых выражений. Особенно тех, которые накладывают условия на упакованные узлы (например, //article[@id eq “1”]). В-третьих, существенно ускоряется скорость сериализации данных. • Узлы, упакованные в текст. Узлы, которые не адресуются запросами (например, элементы визуализации) могут храниться в сериализованном текстовом виде. Это позволяет существенно 151
Рис. 4: Пример внутреннего представления данных. На рис. 4 показан план хранения для примера, приведенного в разд. 2. В соответствии с этим планом получается следующее: •
• •
152
Узлы article и link представляются в структурном виде с использованием дескрипторов узлов. Это связано с тем, что эти узлы напрямую запрашиваются и сериализуются в запросах Q1-Q5. При этом метки описывающей схемы и указатели на братьев не хранятся, поскольку они не используются для выполнения запросов. Атрибуты id и idref упакованы в дескрипторы родительских узлов, поскольку по ним производится поиск для извлечения этих родительских узлов. Узел title запрашивается и сериализуется в путевых выражениях запросов Q1-Q5, поэтому он также «уплощается».
•
Узлы author и другие дети узла article упакованы в текстовые представления. При сериализации узла article, заглушки #id, #title и #link заменяются полями id, title и link соответственно.
5. Близкие работы Нам известно очень небольшое число работ посвященных методам хранения XML данных с возможность оптимизации под приложение. В системе OrientStore [13] был предложен подход, в котором комбинируются способы представления данных, предложенные в системах Natix [2] и Senda [4]. Однако подход системы OrientStore не предполагает анализ запросов и основан только на анализе схемы данных. Кроме того, внутреннее представление поддерживает все возможности модели данных XQuery, что зачастую является избыточным, как мы показали в этой статье. Подходы к хранению данных, предложенные в системах LegoDB [14, 15] или XCacheDB [21], очень близки к подходам, предложенным в этой статье. Тем не менее, эти системы полностью построены над реляционными системами, что накладывает свои ограничения и вызывает дополнительные накладные расходы. Предложенные в этой статье идеи не следует путать с так называемым подходом компонентных баз данных (component databases) [16, 17]. По нашему мнению, компонентные база данных являются общим подходом, который не допускает эффективной реализации на практике. В отличие от компонентных баз данных, мы не предлагаем общей системы, предназначенной для принципиально различных классов приложений (таких как OLTP, OLAP и другие) и принципиально различных аппаратных платформ (таких как PDA, персональные компьютеры, серверы и другие). Предложенные в этой статье идеи ограничиваются расширением оптимизации запросов на оптимизацию структур хранения с целью избавления от избыточных свойств модели данных XQuery.
6. Заключение и будущие работы В данной статье были предложены методы оптимизации структур физического хранения XML данных для эффективного выполнения запросов из предопределенной рабочей нагрузки. Нами были описаны только предварительные результаты, однако предварительные эксперименты подтверждают действенность предложенного подхода. Он позволяет существенно сократить размер внутреннего представления, а также увеличить скорость выполнения запросов. Основным результатом данной работы должно стать создание системы, реализующей модель данных XQuery достаточно эффективно для использования XQuery-систем на практике. В будущих работах мы планируем разработать формальные методы анализа запросов, позволяющие автоматически строить планы хранения данных. Кроме того, мы 153
планируем создать методы, позволяющие производить реорганизацию базы данных без необходимости ее остановки.
эффективную
Литература [1] XQuery 1.0: An XML Query Language. W3C Recommendation 23 January 2007, w3.org/TR/2007/REC-xquery-20070123 [2] T. Fiebig, S. Helmer et al. Anatomy of a Native XML Base Management System, The VLDB Journal 11/ 4, 2002 [3] M. Nicola, B. van der Linden. Native XML support in DB2 universal database. In Proceedings of the VLDB, Trondheim, Norway, 2005 [4] M. Grinev, A. Fomichev, S. Kuznetsov, K. Antipin, A. Boldakov, D. Lizorkin, L. Novak, M. Rekouts, P. Pleshachkov. Sedna: A Native XML DBMS, www.modis.ispras.ru/sedna [5] M. Haustein, T. Härder. An efficient infrastructure for native transactional XML processing. Data Knowledge Eng., June 2007 [6] E. Ehrli. Walkthrough: Word 2007 XML Format Microsoft Corporation, June 2006 [7] Издательство “Большая Российская Энциклопедия", http://www.greatbook.ru/ [8] S. Chandrasekaran, R. Bamford. Shared Cache - The Future of Parallel Databases. In Proceedings of the ICDE, 2003. [9] A. Fomichev, M. Grinev, S Kuznetsov. Descriptive Schema Driven XML Storage. Technical Report, MODIS, Institute for System Programming of the Russian Academy of Sciences, 2004 [10] Join methods in partitioned database environments, IBM DB2 Database Information Center, http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp [11] J. Dean, S. Ghemawat. MapReduce: Simplified Data Processing on Large Clusters. OSDI, December 2004 [12] H. Berenson, P. Bernstein, J. Gray, J. Melton, E. O'Neil, P. O'Neil. A Critique of ANSI SQL Isolation Levels. SIGMOD International Conference on Management of Data San Jose, May 1995 [13] X. Meng, D. Luo, M. Lee, J. An. OrientStore: A Schema Based Native XML Storage System. In Proceedings of the VLDB, 2003 [14] P. Bohannon, J. Freire, J. R. Haritsa, M. Ramanath, P. Roy, J. Siméon: Bridging the XML Relational Divide with LegoDB. In Proceedings of the ICDE, 2003. [15] M. Ramanath, J. Freire, J. Haritsa, and P. Roy. Searching for Efficient XML to Relational Mappings. Technical Report, DSL/SERC, Indian Institute of Science, 2003 [16] M. Seltzer. Beyond Relational Databases: There is More to Data Access than SQL, ACM Queue 3/3, April 2005. [17] S. Chaudhuri, G. Weikum. Rethinking Database System Architecture: Towards a SelfTuning RISC-Style Database System. The VLDB Journal, 2000 [18] D. Florescu et al. The BEA Streaming XQuery Processor. The VLDB Journal 13/3, September 2004 [19] Q. Li, B. Moon. Indexing and Querying XML Data for Regular Path Expressions. Proceedings of the VLDB Conference, Roma, Italy, 2001 [20] H. Garcia-Molina, J. Ullman, J. Widom. Database Systems: The Complete Book. Prentice Hall, October 2001
154
Анализ текстовых документов для извлечения тематически сгруппированных ключевых терминов Мария Гринева, Максим Гринев {upa|maxim}@grinev.net Аннотация. В статье предлагается новый метод извлечения ключевых терминов из текстовых документов. В качестве важной особенности метода мы отмечаем тот факт, что результатом его работы являются группы ключевых терминов; при этом термины из каждой группы семантически связаны одной из основных тем документа. Метод основан на комбинации следующих двух техник: мера семантической близости терминов, посчитанная с использованием Википедии; алгоритм для обнаружения сообществ в сетях. Одним из преимуществ нашего метода является отсутствие необходимости в предварительном обучении, поскольку метод работает с базой знаний Википедии. Экспериментальная оценка метода показала, что он извлекает ключевые термины с высокой точностью и полнотой.
1. Введение Ключевыми терминами (ключевыми словами или ключевыми фразами) являются важные термины в документе, которые могут дать высокоуровневое описание содержания документа для читателя. Извлечение ключевых терминов является базисным этапом для многих задач обработки естественного языка, таких как классификация документов, кластеризация документов, суммаризация текста и вывод общей темы документа [7]. В этой статье мы предлагаем метод для извлечения ключевых терминов документа, используя Википедию в качестве ресурса, насыщенного информацией о семантической близости терминов. Википедия (www.wikipedia.org) – свободно распространяемая энциклопедия, на сегодняшний день являющаяся самой большой энциклопедией в мире. Она содержит миллионы статей, доступных на нескольких языках. В сентябре 2008 года Википедия содержит более 2.5 миллионов статей (более 6 миллионов, если считать перенаправляющие страницы, представляющие синонимы заголовка основной статьи). Обладая огромной сетью ссылок между статьями, большим числом категорий, перенаправляющих страниц (redirect pages) и страниц для многозначных терминов (disambiguation pages), Википедия представляет собой исключительно мощный ресурс для нашей работы и для 155
многих других приложений обработки естественного языка и информационного поиска. В основе нашего метода лежит использование следующих двух техник: мера семантической близости, посчитанная по Википедии, и алгоритм анализа сетей, а именно, алгоритм Гирвана-Ньюмана для обнаружения сообществ в сетях. Ниже мы дадим краткое описание этих техник. Установление семантической близости концепций в Википедии является естественным шагом на пути к построению инструмента, полезного для задач обработки естественного языка и информационного поиска. За последние три года появилось порядочное количество работ по вычислению семантической близости между концепциями с использованием различных подходов [13,14,4,19,21]. Работа [14] дает развернутый обзор многих существующих методов подсчета семантической близости концепций с использованием Википедии. Хотя метод, описываемый в нашей работе, не устанавливает каких-либо требований к способу определения семантической близости, эффективность работы метода зависит от качества работы выбранного метода подсчета семантической близости. Для экспериментов, описанных в этой работе, мы использовали метод подсчета семантической близости, описанный в работе Д. Турдакова и П. Велихова [21]. Зная семантическую близость терминов, мы можем построить семантический граф для всех терминов обрабатываемого документа. Семантический граф представляет собой взвешенный граф, в котором узлами являются термины документа, наличие ребра между парой терминов означает, что эти два термина семантически близки, весом ребра является численное значение семантической близости этих двух терминов. Мы заметили, что граф, построенный таким образом, обладает важным свойством: семантически близкие термины «сбиваются» в плотные подграфы, в так называемые сообщества, наиболее массивные и сильно связанные подграфы, как правило, соотносятся с главными темами документа, и термины, входящие в такие подграфы, являются ключевыми для данного документа. Новшество нашего подхода состоит в применении алгоритма обнаружения сообществ в сетях, который позволяет нам выявить тематические группы терминов, и затем выбрать из них наиболее плотные. Такие наиболее плотные группы терминов являются результатом работы метода – тематически сгруппированными ключевыми терминами. Задача анализа структуры сетей и обнаружения сообществ в них на сегодняшний день хорошо изучена. Было предложено много алгоритмов, которые с успехом применялись для анализа социальных сетей [22], сетей цитирования научных статей [16, 3], сетей покупок товаров крупных Интернет-магазинов таких как Amazon [1], биохимических сетей [6] и многих других. В то же время авторам данной работы неизвестны примеры применения таких алгоритмов к сетям, построенным на основе Википедии. В нашем методе используется алгоритм, предложенный М. Ньюманом и 156
М. Гирваном [15]. Существуют работы, показывающие, что данный алгоритм является высокоэффективным при анализе как синтетических сетей, так и сетей реального мира.
2. Близкие работы В области статистической обработки естественного языка существуют классические подходы к извлечению ключевых терминов: tf.idf и анализ колокаций (collocation analysis) [7]. Tf.idf (term frequency-inverse document frequency) является популярной метрикой при решении задач информационного поиска и анализа текста [17]. Tf.idf представляет собой статистическую меру того, насколько термин важен в документе, который является частью коллекции документов. С использованием Tf.idf важность термина пропорциональна количеству встречаемости термина в документе и обратно пропорциональна количеству встречаемости термина во всей коллекции документов. В то время как tf.idf используется для извлечения ключевых терминов, состоящих из одного слова, анализ коллокаций используется для обнаружения фраз. Подход Tf.idf, дополненный анализом коллокаций, позволяет извлечь ключевые фразы. Оба подхода требуют наличия некоторой коллекции документов для сбора статистики; такую коллекцию документов называют обучающим множеством. Качества работы подходов зависит от того, насколько удачно подобрано обучающее множество. Преимуществом данных подходов является простота реализации и удовлетворительное качество работы, когда обучающее множество хорошо подобрано. Благодаря этим преимуществам данные подходы широко распространены на практике. Мы бы хотели отметить интересный факт: существуют работы [9,11,2,8], где Википедия использовалась в качестве обучающего множества, и было показано, что Википедия может служить хорошим обучающим множеством для многих практических приложений. Существует альтернативный класс подходов к решению задач обработки естественного языка (извлечение ключевых слов является одной из таких задач), и данная работа принадлежит к этому классу подходов. Подходы этого класса основаны на использовании знании о семантической близости терминов. Семантическая близость терминов может быть получена при помощи словаря или тезауруса (например, WordNet [12]), но нас интересуют работы, использующие семантическую близость терминов, полученную по Википедии. Посчитать семантическую близость терминов с использованием Википедии можно двумя способами: используя гипертекстовые ссылки между статьями Википедии, которые соответствуют данным терминам [13,14,21], или измеряя косинус угла между векторами, построенными по текстам соответствующих статей Википедии [4]. Существует множество работ, где семантическая 157
близость терминов, полученная по Википедии, используется для решения следующих задач обработки естественного языка и информационного поиска: разрешение лексической многозначности термина [10,18,8,21], выведение общей темы документа [20], категоризация [5], разрешение кореферентности (coreference resolution) [19]. Авторам данной статьи неизвестны работы, где семантическая близость терминов использовалась бы для извлечения ключевых терминов документа, однако, работа [5] является наиболее близкой к нашей. В работе [5] решается задача категоризации текста, при этом из терминов текста строится семантический граф, аналогично тому, как мы предлагаем в данной работе. Идея применения алгоритмов анализа графов в этой работе проявляется в простой форме: выбираются наиболее центральные термины в графе при помощи алгоритма оценки центральности (betweenness centrality), далее эти термины используются для категоризации документа. Мы выделяем следующие преимущества нашего метода:
Наш метод не требует обучения, в отличие от описанных традиционных подходов. Благодаря тому, что Википедия является крупномасштабной и постоянно обновляемой миллионами людей энциклопедией, она остается актуальной и покрывает много специфических областей знаний. Таким образом, практически любой документ, большая часть терминов которого описана в Википедии, может быть обработан нашим методом. Ключевые термины сгруппированы по темам, и метод извлекает столько различных тематических групп терминов, сколько различных тем покрывается в документе. Тематически сгруппированные ключевые термины могут значительно улучшить выведение общей темы документа (используя, например, применение метода «spreading activation» по графу категорий Википедии, как описано в [20]), и категоризацию документа [5]. Наш метод высокоэффективен с точки зрения качества извлеченных ключевых терминов. Экспериментальные оценки метода, обсуждаемые далее в этой статье, показали, что метод извлекает ключевые термины из документов с высокой точностью и полнотой.
3. Метод извлечения ключевых терминов Метод состоит из следующих пяти шагов: 1) извлечение терминовкандидатов; 2) разрешение лексической многозначности терминов; 3) построение семантического графа; 4) обнаружение сообществ в семантическом графе; 5) выбор подходящих сообществ.
158
3.1. Извлечение терминов-кандидатов Целью этого шага является извлечение всех терминов документа и подготовка для каждого термина набора статей Википедии, который потенциально могут описывать его значение. Мы разбираем исходный документ на лексемы, выделяя все возможные Nграммы. Для каждой N-граммы мы строим ее морфологические вариации. Далее для каждой из вариации производится поиск по всем заголовкам статей Википедии. Таким образом, для каждой N-граммы мы получаем набор статей Википедии, которые могут описывать ее значение. Построение различных морфологических форм слов позволяет нам расширить поиск по заголовкам статьей Википедии и, таким образом, находить соответствующие статьи для большей порции терминов. Например, слова drinks, drinking и drink могут быть связаны с двумя статьями Википедии: Drink и Drinking.
тезауруса позволяет нам избежать данной проблемы: все ключевые термины, полученные в результате работы нашего метода, являются осмысленными фразами. Результатом работы данного шага является список терминов, в котором каждый термин соотнесен с одной соответствующей статьей Википедии, описывающей его значение.
3.3. Построение семантического графа На данном шаге по списку терминов, полученном на предыдущем шаге, мы строим семантический граф. Семантический граф представляет собой взвешенный граф, вершинами которого являются термины документа, наличие ребра между двумя вершинами означает тот факт, что термины семантически связаны между собой, вес ребра является численным значением семантической близости двух терминов, которые соединяет данное ребро.
3.2. Разрешение лексической многозначности терминов На данном шаге для каждой N-граммы мы должны выбрать наиболее подходящую статью Википедии из набора статей, который был построен для нее на предыдущем шаге. Многозначность слов – распространенное явление естественного языка. Например, слово «платформа» может означать железнодорожную платформу, или платформу программного обеспечения, а также платформу, как часть обуви. Правильное значение многозначного слова может быть установлено при помощи контекста, в котором это слово упоминается. Задача разрешения лексической многозначности слова представляет собой автоматический выбор наиболее подходящего значения слова (в нашем случае – наиболее подходящей статьи Википедии) при упоминании его в некотором контексте. Существует ряд работ по разрешению лексической неоднозначности терминов с использованием Википедии [21,8,18,10,11]. Для экспериментов, обсуждаемых в данной работе, был реализован метод, предложенный Д. Турдаковым и П. Велиховым в работе [21]. В [21] авторы используют страницы для многозначных терминов и перенаправляющие страницы Википедии. С использованием таких страниц Википедии строится набор возможных значений термина. Далее наиболее подходящее значение выбирается при помощи знаний о семантической близости терминов: для каждого возможного значения термина вычисляется степень его семантической близости с контекстом. В итоге выбирается то значение термина, степень семантической близости с контекстом которого было наибольшим. Распространенной проблемой традиционных методов извлечения ключевых терминов является наличие абсурдных фраз в результате, таких как, например, "using", "electric cars are". Использование Википедии как контролирующего 159
Рис. 1. Пример семантического графа, построенного по новостной статье «Apple to Make ITunes More Accessible For the Blind» Рис. 1 демонстрирует пример семантического графа, построенного из новостной статьи «Apple to Make ITunes More Accessible For the Blind». В статье говорится о том, что главный прокурор штата Массачусетс и Национальная Федерация Слепых достигли соглашения с корпорацией Apple Inc., следуя которому Apple сделает доступным свой музыкальный Интернетсервис ITunes для слепых пользователей посредством технологии screenreading. На рис. 1 можно видеть, что термины, релевантные Apple Inc. и 160
Blindness, образуют два доминантных сообщества, а термины Student, Retailing и Year оказались на периферии и слабо связаны с остальным графом. Важно отметить тот факт, что термины – ошибки, возникшие при разрешении лексической многозначности терминов, проведенного на втором шаге, оказываются периферийными или даже изолированными вершинами графа, и не примыкают к доминантным сообществам.
3.4. Обнаружение сообществ в семантическом графе Целью данного шага является автоматическое обнаружение сообществ в построенном семантическом графе. Для решения этой задачи мы применяем алгоритм Гирвана-Ньюмана. В результате работы алгоритма исходный граф разбивается на подграфы, которые представляют собой тематические сообщества терминов. Для оценки качества разбиения некоторого графа на сообщества авторы [15] предложили использовать меру модулярности (modularity) графа. Модулярность графа является свойством графа и некоторого его разбиения на подграфы. Она является мерой того, насколько данное разбиение качественно в том смысле, что существует много ребер, лежащих внутри сообществ, и мало ребер, лежащих вне сообществ (соединяющих сообщества между собой). На практике значение модулярности, лежащее в диапазоне от 0.3 до 0.7, означает, что сеть имеет вполне различимую структуру с сообществами, и применение алгоритма обнаружения сообществ имеет смысл. Мы отметили, что семантические графы, построенные из текстовых документов (таких как, например, новостная статья, или научная статья), имеют значение модулярности от 0.3 до 0.5.
3.5. Выбор подходящих сообществ На данном шаге из всех сообществ необходимо выбрать те, которые содержат ключевые термины. Мы ранжируем все сообщества таким образом, чтобы сообщества с высокими рангами содержали важные термины (ключевые термины), а сообщества с низкими рангами – незначимые термины, а также ошибки разрешения лексической многозначности терминов, которые могут возникнуть на втором шаге работы нашего метода. Ранжирование основано на использовании плотности и информативности сообщества. Плотностью сообщества является сумма весов ребер, соединяющих вершины этого сообщества. Экспериментируя с традиционными подходами, мы обнаружили, что использование меры tf.idf терминов помогает улучшить ранжирование сообществ. Tf.idf дает большие коэффициенты терминам, соответствующим именованным сущностям (например, Apple Inc., Steve Jobs, Braille), а терминам, соответствующим общим понятиям (таким как, например, Consumer, Year, Student) дает низкие коэффициенты. Мы считаем tf.idf для терминов, используя Википедию так, как описано в работе [8]. Под 161
информативностью сообщества мы понимаем сумму tf.idf-терминов, входящих в это сообщество, деленную на количество терминов сообщества. В итоге, мы считаем ранг сообщества, как плотность сообщества, умноженная на его информативность, и сортирует сообщества по убыванию их рангов. Приложение, использующее наш метод для извлечения ключевых слов, может использовать любое количество сообществ с наивысшими рангами, однако, на практике имеет смысл использовать 1-3 сообщества с наивысшими рангами.
4. Экспериментальная оценка В этом разделе мы обсудим экспериментальные оценки предложенного метода. Поскольку не существуют стандартных бенчмарков для измерения качества извлеченных из текстов ключевых терминов, мы провели эксперименты с привлечением ручного труда, то есть полнота и точность извлеченных ключевых слов оценивались людьми – участниками эксперимента. Мы собрали 30 блог-постов из следующих блогов технической тематики: «Geeking with Greg», автор Грег Линден, DBMS2, автор Курт Монаш, Stanford Infoblog, авторы – члены группы Stanford Infolab. В эксперименте приняли участие пять человек из отдела информационных систем ИСП РАН. Каждый участник должен был прочитать каждый блог-пост и выбрать в нем от 5 до 10 ключевых терминов. Каждый ключевой термин должен присутствовать в блог-посте, и для него должно быть найдено соответствующая статья в Википедии. Участники также были проинструктированы выбирать ключевые слова так, чтобы они покрывали все основные темы блог-поста. В итоге для каждого блог-поста мы выбрали такие ключевые термины, которые были выделены, по крайней мере, двумя участниками эксперимента. Названия перенаправляющих статей Википедии и название статей, на которые идет перенаправление, по сути, представляют собой синонимы, и мы в нашем эксперименте считали их одним термином. Метод, представленный в данной статье, был реализован по следующим архитектурным принципам. Для достижения лучшей производительности мы не вычисляли семантическую близость всех пар терминов Википедии заранее. Данные, необходимые для подсчета семантической близости терминов на лету, а именно, заголовки статей Википедии, информация о ссылках между статьями, статистическая информация о терминах были загружены в оперативную память. В итоге полученная база знаний занимала в оперативной памяти 4.5 Гбайта. База знаний была установлена на выделенном компьютере с размером оперативной памяти, равным 8 Гбайт. Клиентское приложение работали с базой знаний посредством вызовов удаленных процедур.
162
4.1. Оценка полноты выделенных ключевых терминов Под полнотой мы понимаем долю ключевых слов, выделенных вручную, которые так же были выделены автоматически нашим методом:
где под {manually extracted} мы понимаем множество ключевых слов, извлеченных вручную участниками эксперимента для некоторого документа, под {automatically extracted} мы понимаем множество всех ключевых терминов, автоматически извлеченных нашим методом для того же документа. Знаком |S| мы обозначаем мощность множества S, то есть количество терминов в множестве S. Для 30 блог-постов мы имеем 180 ключевых терминов, выделенных участниками эксперимента вручную, 297 – выделенных автоматически, 127 вручную выделенных ключевых слов были также выделены автоматически. Таким образом, полнота равно 68%.
4.2. Оценка точности выделенных ключевых терминов Мы оцениваем точность, используя ту же методологию, которой пользовались для оценки полноты. Под точностью мы понимаем долю тех слов, автоматически выделенных нашим методом, которые также были выделены вручную участниками эксперимента:
Итого, следуя показателям нашей тестовой коллекции, точность равна 41%.
4.3. Пересмотр оценки полноты и точности С целью более качественной оценки работы метода мы также пересмотрели наши оценки полноты и точности. Важной особенностью нашего метода является факт, что он в среднем выделяет больше ключевых слов, чем человек. Более точно, наш метод обычно извлекает больше ключевых терминов, релевантных одной теме. Например, рассмотрим рис. 1. Для темы, относящейся к Apple Inc., наш метод выделяет термины: Internet, Information access, Music download, Apple Inc., ITunes, Apple Keyboard и Steve Jobs, в то время как человек обычно выделяет меньше терминов и склонен выделять имена и названия: Music download, Apple Inc., ITunes и Steve Jobs. Это означает, что, иногда метод извлекает ключевые термины с лучшим покрытием основных тем документа, чем это делает человек. Этот факт побудил нас пересмотреть оценку полноты и точности работы нашего метода. 163
Каждый участник эксперимента был проинструктирован пересмотреть ключевые термины, которые он сам выделил следующим образом. Для каждого блог-поста он должен был изучить ключевые термины, выделенные автоматически, и, по возможности, расширить свой набор ключевых слов, то есть дополнить его теми терминами, которые, по его мнению, относятся к главным темам документа, но не были выделены на первом этапе. После такого пересмотра, мы получили 213 ключевых слов, выделенных вручную (вместо 180), таким образом, участники эксперимента добавили 33 новых ключевых термина, что означает, что наше предположение имело смысл, и такой пересмотр важен для полноценной оценки работы метода. В итоге, полнота равна 73% и точность – 52%.
5. Заключение Мы предложили новый метод для извлечения ключевых терминов из текстовых документов. Одним из преимуществ нашего метода является отсутствие необходимости в предварительном обучении, поскольку метод работает над базой знаний, построенной из Википедии. Важной особенностью нашего метода является форма, в которой он выдает результат: ключевые термины, полученные из документа, сгруппированы по темам этого документа. Сгруппированные по темам ключевые термины могут значительно облегчить дальнейшую категоризацию данного документа и выведение его общей темы. Эксперименты, проведенные с использованием ручного труда, показали, что наш метод позволяет извлекать ключевые термины с точностью и полнотой, сравнимой с теми, что дают современные существующие методы. Мы отметили, что наш метод может быть с успехом применен для очистки сложных составных документов от неважной информации, и выделения главной темы в них. Это означает, что его интересно было бы применить для выделения ключевых терминов из Web-страниц, которые, как правило, загружены второстепенной информацией, например, меню, навигационные элементы, реклама. Это направление дальнейшей работы. Список литературы [1] Clauset, A.; Newman, M. E. J.; and Moore, C. 2004. Finding community structure in very large networks. Physical Review E 70:066111. [2] Dakka, W., and Ipeirotis, P. G. 2008. Automatic extraction of useful facet hierarchies from text databases. In ICDE, 466–475. IEEE. [3] de Solla Price, D. J. 1965. Networks of scientific papers. Science 169:510–515. [4] Gabrilovich, E., and Markovitch, S. 2007. Computing semantic relatedness using wikipedia-based explicit semantic analysis. In Proceedings of The Twentieth International Joint Conference for Artificial Intelligence, 1606–1611. [5] Janik, M., and Kochut, K. J. 2008. Wikipedia in action: Ontological knowledge in text categorization. International Conference on Semantic Computing, 268–275.
164
[6] Kauffman, S. A. 1969. Metabolic stability and epigenesist in randomly constructed genetic nets. J Theor Biol 22(3):437–467. [7] Manning, C. D., and Schtze, H. 1999. Foundations of Statistical Natural Language Processing. The MIT Press. [8] Medelyan, O.; Witten, I. H.; and Milne, D. 2008. Topic indexing with wikipedia. In Wikipedia and AI workshop at the AAAI-08 Conference (WikiAI08). [9] Mihalcea, R., and Csomai, A. 2007. Wikify!: linking documents to encyclopedic knowledge. In CIKM ’07: Proceedings of the sixteenth ACM conference on Conference on information and knowledge management, 233–242. New York, NY, USA: ACM. [10] Mihalcea, R. 2005. Unsupervised large-vocabulary word sense disambiguation with graph-based algorithms for sequence data labeling. In HLT ’05: Proceedings of the conference on Human Language Technology and Empirical Methods in Natural Language Processing, 411–418. Morristown, NJ, USA: Association for Computational Linguistics. [11] Mihalcea, R. 2007. Using wikipedia for automatic word sense disambiguation. [12] Miller, G. A.; Fellbaum, C.; Tengi, R.; Wakefield, P.; Langone, H.; and Haskell, B. R. Wordnet: a lexical database for the english language. http://wordnet.princeton.edu/. [13] Milne, D., and Witten, I. 2008. An effective, low-cost measure of semantic relatedness obtained from wikipedia links. In Wikipedia and AI workshop at the AAAI-08 Conference (WikiAI08). [14] Milne, D. 2007. Computing semantic relatedness using wikipedia link structure. In Proceedings of the New Zealand Computer Science Research Student Conference (NZCSRSC). [15] Newman, M. E. J., and Girvan, M. 2004. Finding and evaluating community structure in networks. Physical Review E 69:026113. [16] Redner, S. 1998. How popular is your paper? An empirical study of the citation distribution. The European Physical Journal B 4:131. [17] Salton, G., and Buckley, C. 1988. Term-weighting approaches in automatic text retrieval. Inf. Process. Manage. 24(5):513–523. [18] Sinha, R., and Mihalcea, R. 2007. Unsupervised graph-based word sense disambiguation using measures of word semantic similarity. In ICSC ’07: Proceedings of the International Conference on Semantic Computing, 363–369. Washington, DC, USA: IEEE Computer Society. [19] Strube, M., and Ponzetto, S. 2006. WikiRelate! Computing semantic relatedness using Wikipedia. In Proceedings of the 21st National Conference on Artificial Intelligence (AAAI-06), 1419–1424. [20] Syed, Z.; Finin, T.; and Joshi, A. 2008. Wikipedia as an Ontology for Describing Documents. In Proceedings of the Second International Conference on Weblogs and Social Media. AAAI Press. [21] Turdakov, D., and Velikhov, P. 2008. Semantic relatedness metric for wikipedia concepts based on link analysis and its application to word sense disambiguation. In Colloquium on Databases and Information Systems (SYRCoDIS). [22] Wasserman, S.; Faust, K.; and Iacobucci, D. 1994. Social Network Analysis: Methods and Applications (Structural Analysis in the Social Sciences). Cambridge University Press.
165