Исследование эффективности автоматической векторизации циклов компиляторами
Описание тестового набора MediaBench II, характеристика автоматической векторизации Intel C/C++. Наборы векторных инструкций, особенности компилятора LLVM/Clang. Алгоритм кодирования MPEG2 и сжатия JPEG. Утилита GNU Make, профилировщик GNU gprof.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 23.05.2018 |
Размер файла | 49,9 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Содержание
- ВВЕДЕНИЕ
- 1. Постановка задачи
- 2. Предметная область
- 2.1 Тестовый набор MediaBench II
- 2.1.1 Алгоритм сжатия JPEG
- 2.1.2 Алгоритм кодирования MPEG2
- 2.2 Утилита GNU Make
- 2.3 Компилятор GCC C/C++
- 2.3.1 Автоматическая векторизация в GCC C/C++
- 2.4 Компилятор LLVM/Clang
- 2.4.1 Автоматическая векторизация в LLVM/Clang
- 2.5 INTEL C/C++ COMPILER
- 2.5.1 Автоматическая векторизация Intel C/C++
- 2.6 Профилировщик GNU gprof
- 2.7 Наборы векторных инструкций
- 3. Организация экспериментОВ
- 3.1 Целевые платформы
- 3.2 Компиляторы
- 3.3 Методология
- 4. Результаты исследования
- 4.1 Ускорение
- 4.2 Векторизация
- 4.3 Анализ функций
- 4.4 Вывод
- Заключение
- Приложение А
- Приложение Б
- Приложение В
- Приложение Г
ВВЕДЕНИЕ
В настоящее время большинство реальных задач, таких как обработка видео, звука, работа с графикой или научные расчеты, требуют выполнения в очень сжатые сроки либо в режиме реального времени (налету), для чего необходимо использование высокопроизводительных вычислительных систем. векторизация кодирование компилятор intel
В то же время, бесконечное увеличение количества транзисторов на кристаллах процессоров невозможно в силу физических ограничений.
Существует множество способов повысить производительность вычислительных систем за счет повышения эффективности выполнения отдельных команд процессора. Одним из таких способов является использование векторных (SIMD) расширений процессоров и специфических для каждого процессора векторных команд, что в совокупности позволяет за одну инструкцию выполнять вычисления над несколькими элементами данных.
Существующие SIMD-расширения для архитектур процессоров IA-32 и Intel 64:
· MMX;
· SSE;
· SSE2;
· SSE3;
· SSE4;
· SSE4.1;
· SSE4.2;
· AVX.
Программист может использовать ассемблерные команды из этих векторных расширений напрямую и сам управлять распределением векторных регистров или использовать типы данных и внутренние функции компиляторов - интринсики (intrinsics). В последнем случае компилятор самостоятельно распределяет векторные регистры. Оба эти подхода обеспечивают низкую переносимость программного кода между различными архитектурами процессоров. Альтернативой является автоматическая векторизация программного кода компиляторами. Этот подход не требует внесения изменений в программу со стороны программиста и обеспечивает высокую переносимость кода.
Критическими участками кода, выполнение которых занимает длительное время во многих программах, являются циклы. В циклах производятся однотипные операции над различными элементами одномерных или многомерных массивов. Векторизация позволяет выполнять эти операции одновременно над несколькими экземплярами данных.
Максимальное ускорение, которое может быть получено с помощью векторных расширений, зависит от ширины векторных регистров. Например, для векторного расширения SSE размер векторных регистров равен 128 бит, поэтому векторные операции будут выполняться в 2, 4, 8 или 16 раз быстрее (в зависимости от используемого типа данных), чем их скалярные аналоги. Поэтому, векторизация программ является одним из преобразований компиляторов, которое может оказать значительное влияние на производительность.
В этой работе проводится исследование эффективности автоматической векторизации циклов компиляторами.
1. Постановка задачи
Цель работы - оценить эффективность автоматической векторизации циклов современными компиляторами и провести анализ полученного ускорения от автоматической векторизации циклов на примере компиляторов: GCC С/С++ (версия 6.3.0), Intel C/C++ (версия 17.0.2), LLVM/Clang (версия 4.0.0).
2. Предметная область
2.1 Тестовый набор MediaBench II
MediaBench II - тестовый набор (benchmark), состоящий из кодеров и декодеров для 6 стандартов сжатия изображения и видео:
· JPEG: кодек сжатия изображения, основанный на алгоритме дискретного косинусного преобразования (DCT);
· JPEG-2000: кодек сжатия изображения, основанный на алгоритмах вейвлет-преобразований;
· H.263: стандарт сжатия видео, предназначенный для передачи видеопотока по каналам передачи данных с низкой пропускной способностью;
· H.264: стандарт сжатия видео, предназначенный для достижения высокой степени сжатия видео;
· MPEG-2: кодек сжатия видео без потерь, основан на алгоритмах поиска и удаления повторений в видеопотоке, называемых избыточностью;
· MPEG-4: кодек сжатия видеопотока для передачи по низкоскоростным каналам передачи данных (около 64 КБ/с).
Другие приложения из этого тестового набора не использовались потому, что в них нет большого количества возможностей для автоматической векторизации компиляторами.
Данный набор приложений создан группой специалистов в области кодирования мультимедиаинформации под руководством Джейсона Фритца и Билла Меджина-Смита с целью предоставления единой метрики для тестирования компиляторов [1].
Требования для разработки данного набора приложений:
· приложения должны осуществлять полноценное тестирование компиляторов, а не только отдельных их аспектов;
· приложения должны быть написаны на Си-подобных языках высокого уровня;
· набор должен состоять из широко распространённых приложений;
· приложения должны быть не похожи друг на друга;
· результаты тестирования должны быть полезны для принятия решения по выбору компилятора.
Из них были выбраны два набора приложений: кодеры и декодеры для JPEG и MPEG-2.
2.1.1 Алгоритм сжатия JPEG
JPEG - алгоритм сжатия изображения как с потерями, так и без них. JPEG предназначен для обработки «реальных» сцен, например, сканированных фотографий. Мультфильмы, чертежи линий и другие нереалистичные изображения не являются для JPEG целевыми. На таком материале можно получить плохое качество изображения и/или небольшое сжатие [5].
JPEG является алгоритмом сжатия изображения как с потерями, так и без них, в зависимости от уровня сжатия, что означает, что выходное изображение необязательно идентично входному изображению. Следовательно, JPEG не надо использовать, если нужно получить побитово одинаковые выходные и входные файлы. Однако на типичных изображениях реального мира очень хорошие высокие сжатия могут быть получены без видимых изменений.
Можно изменять соотношение качества изображения и размера файла с помощью настройки «качество» компрессора. Для сжатия изображений в формате JPEG применяется алгоритм дискретного косинусного преобразования (DCT) [6].
Тестовый набор MediaBench II содержит компрессор и декомпрессор изображения.
В листинге 3.1 показан пример запуска приложений кодера и декодера JPEG.
Листинг 3.1 - Демонстрационная запуска кодера и декодера JPEG.
/cjpeg -dct float -quality 75 -outfile output_base_4CIF_96bps.jpg input_base_4CIF.ppm
./djpeg -dct float -ppm -outfile output_base_4CIF_96bps.ppm output_base_4CIF_96bps.jpg
Для автоматизации сборки набора кодера и декодера используются утилита Make с предварительно настроенными скриптами, код Make-файла находится в приложении В.
2.1.2 Алгоритм кодирования MPEG2
MPEG2 представляет собой набор стандартов кодирования видео- и аудиосигналов. В частном случае образец приложения кодирования и декодирования видеопотока также использует алгоритм дискретного косинусного преобразования.
Тестовый набор MediaBench II содержит реализации mpeg2decode и mpeg2encode:
· программа mpeg2decode - это реализация ISO/IEC DIS 13818-2 декодера. Он преобразует видеопотоки MPEG-1 и MPEG-2 в несжатое видео;
· программа mpeg2encode - второй публичный выпуск MPEG-2 кодировщика. Он преобразует упорядоченный набор несжатых входных изображений в сжатый битовый поток, соответствующий ISO/IEC 13818-2 DIS (MPEG-2) [1].
В листинге 3.2 показан пример запуска приложений кодера и декодера MPEG-2.
Листинг 3.2 - Демонстрационная запуска кодера и декодера MPEG-2
./mpeg2decode -b input_base_4CIF_96bps.mpg -o3 output_base_4CIF_96bps_%03d
./mpeg2encode input_base_4CIF_96bps_15.par output_base_4CIF_96bps_15.mpg
Для автоматизации сборки набора кодера и декодера используется утилита Make с предварительно настроенными скриптами, код Make-файла находится в приложении Г.
2.2 Утилита GNU Make
GNU Make - это утилита предназначенная для автоматизации сборки проектов. Для автоматизации генерации исполняемых файлов перед запуском утилиты, необходимо подготовить специальный скрипт - Make файл.
Возможности Make:
· Make позволяет конечному пользователю программного кода производить сборку и установку вашего пакета, не зная подробностей о том, как это делается, потому что эти данные могут быть записаны в Make-файл, который вы поставляете;
· Утилита автоматически определяет какие файлы были изменены и соответственно производит компиляцию только этих файлов, а так же определяет связи между файлами, и собирает производит пересборку зависимых;
В Листинге 3.3 показан пример Make-файла:
Листинг 3.3 - Пример Make-файла
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
cpp.o: $(CC)
$(CFLAGS) $< -o $@
2.3 Компилятор GCC C/C++
GNU Compiler Collection (GCC) - набор компиляторов, способных производить оптимизацию и векторизацию кода.
Кроме С/С++ GCC поддерживает компиляцию кода, написанного на языках:
· Objective-C;
· Fortran;
· Ada;
· Go.
GNU GCC является свободным программным обеспечением, поддерживается и распространяется фондом свободного программного обеспечения (Free Software Foundation) на условиях, предусмотренных лицензиями GNU GPL и GNU LGPL. GCC является основным стандартным компилятором для свободно распространяемых UNIX-подобных операционных систем.
Первая версия компилятора была реализована Ричардом Столлманом в 1985 году на языке Pascal. Позже, в 1987 году, компилятор был переписан на языке Си.
GCC - один из ведущих компиляторов по количеству поддерживаемых им процессоров и операционных систем [2]. Сообщество разработчиков GCC стремится регулярно производить обновление набора компиляторов для различных целей.
Основные решения о внесении изменений в GCC принимается руководящим комитетом, исходя из начальных целей.
2.3.1 Автоматическая векторизация в GCC C/C++
Автоматическая векторизация кода в GCC происходит при следующих условиях:
· рассматриваемый цикл - внутренний;
· цикл должен быть определённой структуры:
o итератор цикла - целочисленный;
o одна точка входа и выхода из цикла;
· тело цикла должно быть без циклов и сложных конструкций;
· итерация цикла должна быть независима от внутреннего состояния;
· типы данных внутри цикла должны быть векторизуемы;
· векторизация должны быть выгодна.
2.4 Компилятор LLVM/Clang
LLVM (Low Level Virtual Machine) представляет собой универсальную систему анализа, трансформации и оптимизации программ. Он был разработан в 2000 году в Университете Иллинойса группой разработчиков, возглавляемой Крисом Латтенером. В настоящее время LLVM используется и разрабатывается ведущими компаниями, такими как Apple и Adobe.
В основе LLVM лежит промежуточное представление кода, над которым можно производить изменения во время компиляции, линковки и выполнения.
LLVM поддерживает генерацию кода для следующих архитектур процессоров:
· x86;
· x86-64;
· ARM;
· PowerPC;
· SPARC;
· MIPS;
· IA-64;
· Alpha.
LLVM написана на C++ и портирована на большинство *nix-систем и Windows.
Clang - представляет из себя транслятор в байт-код LLVM для языков высокого уровня, таких как:
· С;
· С++;
· Objective-c;
· Objective-C++;
· OpenCL C.
После трансляции кода фреймворк LLVM производит последующие оптимизацию, векторизацию и кодогенерацию.
Целью разработки данного транслятора и фреймворка является замена компилятора GCC. В отличие от GCC, связка фреймворка LLVM и транслятора Clang стремится предоставить программисту и среде разработки универсальный фреймворк для парсинга, анализа и компиляции кода [3-4].
2.4.1 Автоматическая векторизация в LLVM/Clang
На данный момент LLVM/Clang поддерживает векторизацию в следующих случаях:
· циклы с неизменным количеством итераций;
· циклы с редукцией;
· циклы с ветвлением;
· циклы с обратной итерацией;
· циклы с разными типами данных;
· векторизация вызванных внутри цикла функций;
· циклы с индукцией;
· циклы с глобально объявленными структурами;
· циклы с частичной развёрткой (unrolling)
2.5 INTEL C/C++ COMPILER
Intel С/C++ Compiler - проприетарный оптимизирующий компилятор, поддерживаемый и разрабатываемый компанией Intel. Его основным преимуществом являются целевые и высокоуровневые оптимизации, специализированные под процессоры Intel.
Основные возможности:
· высокоуровневая оптимизация;
· межпроцедурная оптимизация;
· автоматическое распараллеливание кода;
· векторизация для SSE, SSE2, SSE3, SSE4, AVX;
· оптимизация с учетом профильной информации.
Компилятор поддерживает стандарты
· OpenMP 3.0;
· OpenMP Cluster;
· MPI.
Одним из недостатков компилятора является частичная несовместимость с GNU расширениями языка С.
2.5.1 Автоматическая векторизация Intel C/C++
В данном компиляторе автоматическая векторизация кода включается при ключе -O2 и выше.
Чтобы данный компилятор смог векторизовать циклы, они должны удовлетворять следующим критериям:
· счётчик цикла должен быть известен при входе в цикл, во время выполнения и не меняться;
· из цикла должен быть один выход. В листинге 3.4 показан пример цикла который не будет векторизован автоматически по причине присутствия внутри цикла условия выхода;
· внутри цикла результат вычисления должен помещаться в одни и те же переменные, даже при наличии ветвления;
· цикл не может быть внешним;
· внутри цикла нет вызовов других функций.
Листинг 3.4 - пример не векторизуемого цикла автоматически
void no_vec(float a[], float b[], float c[])
{
int i = 0.;
while (i < 100)
{
a[i] = b[i] * c[i];
if (a[i] < 0.0)
break;
++i;
}
}
Также препятствием для векторизатора может быть:
· непоследовательный доступ к памяти. Так происходит, когда шаг цикла не равен единице.
· зависимость по данным. Векторизация цикла влечёт за собой изменение порядка операций в цикле, так как каждая SIMD команда работает с несколькими элементами данных одновременно.
2.6 Профилировщик GNU gprof
GNU gprof - стандартный профилировщик программного кода для UNIX-совместимых приложений. Он используется для анализа выполнения больших программ, разбор которых вручную представляет собой слишком трудоёмкую задачу. gprof позволяет получить информацию о времени выполнения всего кода, отдельных его участков, о функциях, вызванных из других функций и определить места в коде, где нужна оптимизация.
GNU gprof использует информацию, которую удалось собрать во время выполнения программы. Чтобы проанализировать работу программы, её нужно скомпилировать со специальными опциями компилятора, разрешающими добавление профилирующей информации.
Результатом работы профилировщика является как «Простой профиль», показывающий время работы программы внутри отдельных функций, так и «Граф вызовов», который позволяет узнать зависимость одних участков кода от других.
GNU gprof может профилировать выполнение программного кода на языках С, C ++, Pascal, Fortran 77 [4].
В листинге 3.5 показан пример использования:
Листинг 3.5 - пример использования GNU gprof
$ gcc -pg -o you_prog you_prog.c
$ ./you_prog
$ gprof ./you_prog
2.7 Наборы векторных инструкций
Практически все архитектуры современных процессоров содержат векторные арифметико-логические устройства (АЛУ), векторные регистры и поддерживают наборы векторных команд.
Векторные расширения процессора содержат некоторое количество дополнительных специализированных регистров, определяемое технологией и разрядностью системы.
· MMX - (Multimedia Extensions - мультимедийные расширения) - SIMD расширение процессора и набор команд для работы с ним. Данное расширение было разработано в компании Intel в первой половине 1990-х годов;
o Включает в себя восемь 64-битных регистра общего пользования (MM0-MM7). Данные регистры совмещены с мантиссами восьми регистров FPU, что не позволяет использовать эти регистры параллельно;
o Расширение включает в себя 57 инструкций, позволяющих осуществлять параллельную обработку нескольких элементов данных.
· SSE - (Streaming SIMD Extension) представляет собой SIMD расширение процессора и набор команд для работы с ним. Расширение было разработано в компании Intel в 1999 году;
o Содержит восемь специализированных 128-битных регистра (XMM0-XMM7);
o Содержит набор из 70 команд.
· SSE2 - (Streaming SIMD Extension 2) SIMD расширение процессора и набор дополнительных команд для работы с ними;
o Расширяет набор команд SSE на 144 команды;
o Среди новых команд присутствуют команды для работы с целочисленными данными, что позволило полностью исключить работу устаревших команд MMX;
o Включает в себя команды для управления кэшем, что позволяет его использовать более рационально;
· SSE3 - (Streaming SIMD Extension 3) третья версия SIMD-расширения Intel, потомок SSE, SSE2. Которое добавляет возможность горизонтального сложения и вычитания внутри одного специализированного регистра;
o Добавляет 13 команд для горизонтальных операций.
· SSSE3 - набор SIMD-инструкций, расширяющий наборы команд предыдущих версий SSE;
o Добавляет 16 команд, которые могут работать как с 64-битными MMX, так и с 128-битными SSE регистрами;
· SSE4 - (Streaming SIMD Extension 4) версия SIMD-расширения Intel. Анонсирован 27 сентября 2006 года.
o Добавляет 54 инструкции.
· AVX - версия SIMD-расширения Intel, которая представлена в 2010 году;
o Количество регистров увеличено до 16 (YMM0-YMM15);
o Ширина векторных регистров расширена до 256 бит;
o Добавлены команды для работы с 256-битными регистрами. Которые включают в себя команды SSE;
o SSE инструкции работают в первых 128 битах AVX регистров.
· AVX2 - версия SIMD-расширения Intel, являющаяся дальнейшим развитием AVX
o Добавлены инструкции для работы с целыми числами;
o Увеличена производительность при обработки чисел с плавающей точкой;
3. Организация экспериментОВ
3.1 Целевые платформы
Для выполнения экспериментов были выбраны процессор Intel i3-2377M и Intel Xeon E5-2620. В таблице 4.1 приведены их описания.
Таблица 4.1 - Описание целевых платформ
Процессор |
SIMD расширения |
Частота, ГГц |
L3 Cache, Мбайт |
ОС |
|
i3-2377M |
MMX, SSE, SSE2, SSE3, SSE4.1, SSE4,2, AVX |
1.5 |
3 |
Ubuntu 17.10 |
|
Xeon E5620 |
MMX, SSE, SSE2, SSE3, SSE4.1, SSE4.2, AVX, AVX2 |
2.66 |
12 |
CentOS 7.3 |
3.2 Компиляторы
Для проведения исследований использовались компиляторы GCC C/C++, LLVM/Clang и Intel C/C++. Версии компиляторов и опции приведены в таблице 4.2.
Таблица 4.2 - Описание версий компиляторов и опций, используемых для проведения экспериментов.
Компилятор |
GCC C/C++ |
LLVM/Clang |
Intel C/C++ |
|
Версия |
6.3.0 |
4.0.0 |
17.0.2 |
|
Оптимизация |
-O3 -ffast-math |
-O3 -ffast-math |
-O3 -xHost |
|
Векторизация |
- |
-fvectorize |
- |
|
Отключение векторизации |
-fno-tree-vectorize |
-fno-vectorize |
-no-vec |
|
Сбор отчётов |
-fopt-info-vec |
-Rpass=loop-vectorize |
-qopt-report3 |
|
Включение профилирующей информации |
-g -pg -static |
-g -pg -static |
-g -pg -static |
3.3 Методология
Цель проведения экспериментов состояла в:
· получении среднего времени выполнения каждого приложения;
· определении ускорения, полученного от автоматической векторизации кода выбранными компиляторами;
· получении и анализе отчетов компиляторов с целью выявления эффективности автоматического векторизатора кода.
Для получения результатов экспериментов выполнялась следующая последовательность действий:
· модификация кодов программ таким образом, чтобы операции кодирования и декодирования для JPEG и MPEG2 выполнялись в цикле по 100 раз. Это позволит максимально уменьшить доверительный интервал времени выполнения;
· расчет среднего времени выполнения каждой итерации;
· для наборов JPEG и MPEG2 подсчет циклов, которые теоретически возможно векторизовать (в расчет берутся только внутренние циклы гнезд циклов);
· компиляция программ обоих приложений для двух целевых платформ с использованием опций, отключающих векторизацию, запуск и замер времени выполнения;
· компиляция программ обоих приложений для двух целевых платформ с использованием опций, отключающих векторизацию и позволяющих получить профилирующую информацию, запуск приложения, получение отчетов gprof;
· компиляция программ с опциями включения векторизации и сбора отчетов, запуск и замер времени выполнения;
· компиляция программ с опциями включения векторизации и получения профилирующей информации, запуск приложения, получение отчетов gprof;
· сбор и анализ отчетов автоматического векторизатора и профилирования программы с помощью GNU gprof. На этом шаге делаются выводы о том, сколько циклов удалось векторизовать и удалось ли векторизовать самые длительные по времени выполнения функции программы.
4. Результаты исследования
4.1 Ускорение
В таблицах 5.1 и 5.2 представлено ускорение, которого удалось достичь, благодаря автоматической векторизации кода каждого приложения из пакета MediaBench II отдельно для платформ i3-2377M и Intel Xeon E5-2620.
Таблица 5.1 - Ускорение для Intel i3-2377M
Компилятор |
JPEG coder |
JPEG decoder |
MPEG2 coder |
MPEG2 decoder |
|
GCC C/C++ |
1,172 |
1,278 |
1,111 |
1,139 |
|
LLVM/Clang |
1,194 |
1,124 |
1,007 |
1,246 |
|
Intel C/C++ |
1,368 |
1,082 |
2,273 |
1,248 |
Таблица 5.2 - Ускорение для Intel Xeon E5-2620
Компилятор |
JPEG coder |
JPEG decoder |
MPEG2 coder |
MPEG2 decoder |
|
GCC C/C++ |
1,696 |
1,046 |
1,072 |
1,067 |
|
LLVM/Clang |
2,140 |
1,060 |
1,002 |
1,021 |
|
Intel C/C++ |
2,138 |
1,164 |
2,201 |
1,126 |
4.2 Векторизация
В таблицах 5.3-5.4 показаны результаты анализа отчетов векторизации для каждого компилятора на двух целевых платформах.
Таблица 5.3 - Результаты векторизации для i3-2377M
JPEG |
MPEG2 |
||||||
GCC С/С++ |
LLVM/Clang |
Intel С/C++ |
GCC С/С++ |
LLVM/Clang |
Intel С/C++ |
||
Векторизовано |
52 |
27 |
147 |
95 |
56 |
89 |
|
Всего циклов |
674 |
674 |
674 |
329 |
329 |
329 |
|
~% Удачных |
7,715 |
4,005 |
21,810 |
28,875 |
17,0212 |
27,051 |
Таблица 5.4 - Результаты векторизации для Xeon E5620
JPEG |
MPEG2 |
||||||
GCC |
LLVM/Clang |
Intel C++ |
GCC |
LLVM/Clang |
Intel C++ |
||
Векторизовано |
60 |
26 |
183 |
91 |
56 |
95 |
|
Всего циклов |
674 |
674 |
674 |
329 |
329 |
329 |
|
~% Удачных |
8,900 |
3,38 |
27,151 |
27,659 |
17,021 |
28,875 |
4.3 Анализ функций
Используя отчеты, полученные с помощью профилировщика GNU gprof и отчеты о векторизации компиляторами, была произведена оценка ускорения часто запускаемых функций, суммарное время выполнения которых составляет большую часть времени выполнения каждого отдельного приложения.
Для набора кодеров и декодеров JPEG результаты анализа показывают, что на обоих целевых платформах автоматически удалось частично векторизовать циклы внутри одной из самых часто вызываемых функций с наибольшим количеством времени, которая программа суммарно проводит внутри этой функции, forward_DCT, которая реализует основные шаги в алгоритме дискретного косинусного преобразования (DCT). Ускорение для функции показано в таблице 5.5. Данные представлены усреднённые для обоих платформ, так как они коррелируют.
Таблица 5.5 - Ускорение для функции forward_DCT
Компилятор |
Ускорение |
|
GCC |
1,141 |
|
LLVM/Clang |
1,316 |
|
Intel С/C++ |
1,314 |
Для набора кодеров и декодеров MPEG-2 не удалось выявить одну функцию, векторизация которой, дала бы наибольший прирост ускорения.
Фактически компиляторы GCC C/C++, LLCM/Clang и Intel C/C++ автоматически могут векторизовать от ~3 до ~30 процентов циклов из набора тестов MediaBench II, что позволяет получить максимальное ускорение в ~210 процентов.
Проанализировав отчёты gprof и циклы внутри самых частых и медленных функций, стало понятно, что теоретически, данный набор приложений можно ускорить в 8 раз, так как на обоих платформах использовались 256 битные расширения AVX и AVX2, а в этих функциях используется тип данных float размером в 4 байта.
Заключение
В данной выпускной квалификационной работе произведена оценка эффективности автоматической векторизации циклов в современных компиляторах и проведён анализ ускорения, полученного от автоматической векторизации циклов, на примере компиляторов: GCC С/С++ (версия 6.3.0), Intel C/C++ (версия 17.0.2), LLVM/Clang (версия 4.0.0).
БИБЛИОГРАФИЯ
1. MediaBench Consortium - Saint Louis University / Department of Computer Science. - URL: http://cs.slu.edu/~jfritts/mediabench/ (Дата обращения 13.06.2017)
2. GCC Wiki - GCC steering committee. - URL: https://gcc.gnu.org/wiki / (Дата обращения 13.06.2017)
3. Сlang: a C language family frontend for LLVM - The LLVM Foundation. - URL: https://clang.llvm.org/index.html (Дата обращения 13.06.2017)
4. Обзор LLVM - Хабрахабр. - URL: https://habrahabr.ru/post/47878/ (Дата обращения 13.06.2017)
5. GNU gprof. - URL: https://sourceware.org/binutils/docs/gprof/ (Дата обращения 13.06.2017)
6. Overview of JPEG. - ISO Members Area. - URL: https://jpeg.org/jpeg/index.html (Дата обращения 13.06.2017)
7. Изобретаем JPEG. - Хабрахабр - URL: https://habrahabr.ru/post/206264/ (Дата обращения 13.06.2017)
Приложение А
Наиболее употребляемые текстовые сокращения
GCC - GNU Compiler Collection
LLVM - Low Level Virtual Machine
MMX - Multimedia Extensions
SSE - Streaming SIMD Extensions
MPEG - Moving Picture Experts Group
AVX - Advanced Vector Extensions
JPEG - Joint Photographic Experts Group
Приложение Б
Листинг Make-файла для сборки JPEG
# Where to install the programs and man pages.
prefix = /usr/local
exec_prefix = ${prefix}
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
binprefix =
manprefix =
manext = 1
mandir = $(prefix)/man/man$(manext)
#VECTLOG= 2>vectlog
VECTLOG=
# The name of your C compiler:
#CC= clang
CC= gcc
#CC= icc
#PGOPT= -g -pg -static
PGOPT =
# You may need to adjust these cc options:
#GCC
# vect
#CFLAGS= $(PGOPT) -O3 -ffast-math -fivopts -march=native -fopt-info-vec -fopt-info-vec-missed -ftree-vectorizer-verbose=2 -I$(srcdir)
#CFLAGS= $(PGOPT) -O3 -mfpmath=sse -fivopts -march=native -fopt-info-vec -fopt-info-vec-missed -fno-tree-vectorize -ftree-vectorizer-verbose=2 -I$(srcdir)
CFLAGS= -O3 -funsafe-math-optimizations -fivopts -march=native -flax-vector-conversions -msse4.2 -I$(srcdir)
#CFLAGS= -O3 -march=native -fivopts -fopt-info-vec -fopt-info-vec-missed -fno-tree-vectorize -ftree-vectorizer-verbose=1
# scalar
#CFLAGS= $(PGOPT) -O3 -ffast-math -fivopts -march=native -fno-tree-vectorize -I$(srcdir)
#GCC FOR gprof
#CFLAGS= -g -pg -static -I$(srcdir)
# -rdynamic
#clang
# vect
#CFLAGS = -O3 -ffast-math -fvectorize -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize -I$(srcdir)
# scalar
#CFLAGS = -O3 -ffast-math -fno-vectorize -I$(srcdir)
#ICC
#vect
#CFLAGS = -O3 -xHost -qopt-report3 -qopt-report-phase=vec,loop -qopt-report-embed -vec_report -I$(srcdir)
#scalar
#CFLAGS = -O3 -xHost -no-vec -I$(srcdir)
# Generally, we recommend defining any configuration symbols in jconfig.h,
# NOT via -D switches here.
# However, any special defines for ansi2knr.c may be included here:
ANSI2KNRFLAGS=
# Link-time cc options:
LDFLAGS=
# To link any special libraries, add the necessary -l commands here.
LDLIBS=
# If using GNU libtool, LIBTOOL references it; if not, LIBTOOL is empty.
LIBTOOL =
# $(O) expands to "lo" if using libtool, plain "o" if not.
# Similarly, $(A) expands to "la" or "a".
O = o
A = a
# Library version ID; libtool uses this for the shared library version number.
# Note: we suggest this match the macro of the same name in jpeglib.h.
JPEG_LIB_VERSION = 62
# Put here the object file name for the correct system-dependent memory
# manager file. For Unix this is usually jmemnobs.o, but you may want
# to use jmemansi.o or jmemname.o if you have limited swap space.
SYSDEPMEM= jmemnobs.$(O)
# miscellaneous OS-dependent stuff
SHELL= /bin/sh
# linker
LN= $(CC)
#LN= $(CC)
# file deletion command
RM= rm -f
# directory creation command
MKDIR= mkdir
# library (.a) file creation command
AR= ar rc
# second step in .a creation (use "touch" if not needed)
AR2= ranlib
# installation program
INSTALL= /usr/bin/install -c
INSTALL_PROGRAM= ${INSTALL}
INSTALL_LIB= ${INSTALL} -m 644
INSTALL_DATA= ${INSTALL} -m 644
# End of configurable options.
# source files: JPEG library proper
LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
jquant2.c jutils.c jmemmgr.c
# memmgr back ends: compile only one of these into a working library
SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
# files included by source files
INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
# documentation, test, and support files
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
coderules.doc filelist.doc change.log
MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
makvms.opt
CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
jconfig.vms
CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \testimgp.jpg
DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
$(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
# library object files common to compression and decompression
COMOBJECTS= jcomapi.$(O) jutils.$(O) jerror.$(O) jmemmgr.$(O) $(SYSDEPMEM)
# compression library object files
CLIBOBJECTS= jcapimin.$(O) jcapistd.$(O) jctrans.$(O) jcparam.$(O) \
jdatadst.$(O) jcinit.$(O) jcmaster.$(O) jcmarker.$(O) jcmainct.$(O) \
jcprepct.$(O) jccoefct.$(O) jccolor.$(O) jcsample.$(O) jchuff.$(O) \
jcphuff.$(O) jcdctmgr.$(O) jfdctfst.$(O) jfdctflt.$(O) \
jfdctint.$(O)
# decompression library object files
DLIBOBJECTS= jdapimin.$(O) jdapistd.$(O) jdtrans.$(O) jdatasrc.$(O) \
jdmaster.$(O) jdinput.$(O) jdmarker.$(O) jdhuff.$(O) jdphuff.$(O) \
jdmainct.$(O) jdcoefct.$(O) jdpostct.$(O) jddctmgr.$(O) \
jidctfst.$(O) jidctflt.$(O) jidctint.$(O) jidctred.$(O) \
jdsample.$(O) jdcolor.$(O) jquant1.$(O) jquant2.$(O) jdmerge.$(O)
# These objectfiles are included in libjpeg.a
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
# object files for sample applications (excluding library files)
COBJECTS= cjpeg.$(O) rdppm.$(O) rdgif.$(O) rdtarga.$(O) rdrle.$(O) \
rdbmp.$(O) rdswitch.$(O) cdjpeg.$(O)
DOBJECTS= djpeg.$(O) wrppm.$(O) wrgif.$(O) wrtarga.$(O) wrrle.$(O) \
wrbmp.$(O) rdcolmap.$(O) cdjpeg.$(O)
TROBJECTS= jpegtran.$(O) rdswitch.$(O) cdjpeg.$(O) transupp.$(O)
all: hpctimer libjpeg.$(A) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
# Special compilation rules to support ansi2knr and libtool.
.SUFFIXES: .lo .la
#$(CC) $(CFLAGS) -o $@ -c $< 2> ./reportgcc-$<.lst
%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $< $(VECTLOG)
# How to compile with libtool.
# .c.lo:
# $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/$*.c
# How to use ansi2knr, when not using libtool.
# .c.o:
# ./ansi2knr $(srcdir)/$*.c knr/$*.c
# $(CC) $(CFLAGS) -c knr/$*.c
# $(RM) knr/$*.c
# How to use ansi2knr AND libtool.
# .c.lo:
# ./ansi2knr $(srcdir)/$*.c knr/$*.c
# $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c knr/$*.c
# $(RM) knr/$*.c
ansi2knr: ansi2knr.c
$(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr $(srcdir)/ansi2knr.c
$(MKDIR) knr
# the library:
# without libtool:
libjpeg.a: $(LIBOBJECTS)
$(RM) libjpeg.a
$(AR) libjpeg.a $(LIBOBJECTS)
$(AR2) libjpeg.a
# with libtool:
libjpeg.la: $(LIBOBJECTS)
$(LIBTOOL) --mode=link $(CC) -o libjpeg.la $(LIBOBJECTS) \
-rpath $(libdir) -version-info $(JPEG_LIB_VERSION)
# sample programs:
cjpeg: hpctimer $(COBJECTS) libjpeg.$(A)
$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.$(A) hpctimer.o $(LDLIBS)
djpeg: hpctimer $(DOBJECTS) libjpeg.$(A)
$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.$(A) hpctimer.o $(LDLIBS)
jpegtran: $(TROBJECTS) libjpeg.$(A)
$(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.$(A) $(LDLIBS)
rdjpgcom: rdjpgcom.$(O)
$(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.$(O) $(LDLIBS)
wrjpgcom: wrjpgcom.$(O)
$(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.$(O) $(LDLIBS)
# Installation rules:
install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom
$(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg
$(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg
$(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran
$(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom
$(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom
$(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext)
$(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext)
$(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext)
$(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
$(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
install-lib: libjpeg.$(A) install-headers
$(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A)
install-headers: jconfig.h
$(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
$(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h
$(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h
$(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
clean:
$(RM) *.o *.lo libjpeg.a libjpeg.la
$(RM) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
$(RM) ansi2knr core testout* config.log config.status
$(RM) -r knr .libs _libs
$(RM) *.optrpt
$(RM) *.lst
distclean: clean
$(RM) Makefile jconfig.h libtool config.cache
test: cjpeg djpeg jpegtran
$(RM) testout*
./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg
./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm
./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
cmp $(srcdir)/testimg.ppm testout.ppm
cmp $(srcdir)/testimg.bmp testout.bmp
cmp $(srcdir)/testimg.jpg testout.jpg
cmp $(srcdir)/testimg.ppm testoutp.ppm
cmp $(srcdir)/testimgp.jpg testoutp.jpg
cmp $(srcdir)/testorig.jpg testoutt.jpg
check: test
# Mistake catcher:
jconfig.h: jconfig.doc
echo You must prepare a system-dependent jconfig.h file.
echo Please read the installation directions in install.doc.
exit 1
# GNU Make likes to know which target names are not really files to be made:
.PHONY: all install install-lib install-headers clean distclean test check
jcapimin.$(O): jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcapistd.$(O): jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jccoefct.$(O): jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jccolor.$(O): jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcdctmgr.$(O): jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jchuff.$(O): jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
jcinit.$(O): jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcmainct.$(O): jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcmarker.$(O): jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcmaster.$(O): jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcomapi.$(O): jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcparam.$(O): jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcphuff.$(O): jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
jcprepct.$(O): jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jcsample.$(O): jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jctrans.$(O): jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdapimin.$(O): jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdapistd.$(O): jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdatadst.$(O): jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
jdatasrc.$(O): jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
jdcoefct.$(O): jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdcolor.$(O): jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jddctmgr.$(O): jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jdhuff.$(O): jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
jdinput.$(O): jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmainct.$(O): jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmarker.$(O): jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmaster.$(O): jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmerge.$(O): jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdphuff.$(O): jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
jdpostct.$(O): jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdsample.$(O): jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdtrans.$(O): jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jerror.$(O): jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
jfdctflt.$(O): jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jfdctfst.$(O): jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jfdctint.$(O): jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jidctflt.$(O): jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jidctfst.$(O): jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jidctint.$(O): jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jidctred.$(O): jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jquant1.$(O): jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jquant2.$(O): jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jutils.$(O): jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jmemmgr.$(O): jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
jmemansi.$(O): jmemansi.c jinclude.h jconfig.h jpegliofb.h jmorecfg.h jpegint.h jerror.h jmemsys.h
jmemname.$(O): jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
jmemnobs.$(O): jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
jmemdos.$(O): jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
jmemmac.$(O): jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
cjpeg.$(O): cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
djpeg.$(O): djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
jpegtran.$(O): jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
rdjpgcom.$(O): rdjpgcom.c jinclude.h jconfig.h
wrjpgcom.$(O): wrjpgcom.c jinclude.h jconfig.h
cdjpeg.$(O): cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdcolmap.$(O): rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdswitch.$(O): rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
transupp.$(O): transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
rdppm.$(O): rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
wrppm.$(O): wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdgif.$(O): rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
wrgif.$(O): wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdtarga.$(O): rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
wrtarga.$(O): wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdbmp.$(O): rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
wrbmp.$(O): wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
rdrle.$(O): rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
wrrle.$(O): wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diplom:
./cjpeg -dct float -quality 75 -outfile output_base_4CIF_96bps.jpg input_base_4CIF.ppm
./djpeg -dct float -ppm -outfile output_base_4CIF_96bps.ppm output_base_4CIF_96bps.jpg
hpctimer: hpctimer.o
#gcc -pg -O0 -Wall -g -std=c11 -c hpctimer.c -o hpctimer.o
#gcc -pg -O0 -Wall -g -std=c11 -c hpctimer.c -o hpctimer.o
hpctimer.o: hpctimer.c hpctimer.h
profcjpeg:
./cjpeg -dct int -quality 75 -outfile output_base_4CIF_96bps.jpg input_base_4CIF.ppm
gprof ./cjpeg ./gmon.out > ./profiling/cjpeg_profiling.txt
profdjpeg:
./djpeg -dct int -ppm -outfile output_base_4CIF_96bps.ppm output_base_4CIF_96bps.jpg
gprof ./djpeg ./gmon.out > ./profiling/djpeg_profiling.txt
profiling: profcjpeg profdjpeg
Приложение Г
Листинг Make-файла для сборки MPEG-2
#REPORTS= 2> ./report-gcc-$<.lst
#REPORTS=
PROF= -g -pg -static
#PROF=
#
# GNU gcc
#
CC= icc
#CC = gcc
#CC= clang
REPORTS= 2> ./report-$(CC)--$<.lst
#REPORTS=
#CFLAGS = -O3 -w
# GCC
# vect
#CFLAGS= $(PROF) -O3 -ffast-math -fivopts -march=native -fopt-info-vec -fopt-info-vec-missed
# scalar
#CFLAGS = $(PROF) -O3 -ffast-math -fivopts -march=native -fno-tree-vectorize
#clang
# vect
CFLAGS = $(PROF) -O3 -ffast-math -fvectorize -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize
# scalar
#CFLAGS = $(PROF) -O3 -ffast-math -fno-vectorize
#ICC
#vect
#CFLAGS = -O3 -xHost -qopt-report3 -qopt-report-phase=vec,loop -qopt-report-embed
#scalar
CFLAGS = $(PROF) -O3 -xHost -no-vec
LL= $(CC)
all: mpeg2decode mpeg2encode
mpeg2decode:
cd src/mpeg2dec; make 'CC=$(CC)' \
'CFLAGS=$(CFLAGS) $(USE_DISP) $(USE_SHMEM) $(INCLUDEDIR)' \
'LIBS=$(LIBS)' 'LIBRARYDIR=$(LIBRARYDIR)' \
'LL=$(LL)' 'REPORTS=$(REPORTS)' 'PROF=$(PROF)'
mpeg2encode:
cd src/mpeg2enc; make 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LL=$(LL)' 'REPORTS=$(REPORTS)' 'PROF=$(PROF)'
pc:
cd src/mpeg2dec; make pc 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LL=$(LL)' 'REPORTS=$(REPORTS)' 'PROF=$(PROF)'
cd src/mpeg2enc; make pc 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LL=$(LL)' 'REPORTS=$(REPORTS)' 'PROF=$(PROF)'
clean:
cd src/mpeg2dec; make clean
cd src/mpeg2enc; make clean
test:
cd verify; ./verify
hpctimer: hpctimer.o
gcc -O0 -Wall -g -std=c11 -c hpctimer.c -o hpctimer.o
hpctimer.o: hpctimer.c hpctimer.h
#diplom:
# ./src/mpeg2enc/mpeg2encode ./src/mpeg2enc/input_base_4CIF_96bps_15.par ./src/mpeg2enc/output_base_4CIF_96bps_15.mpg
# ./src/mpeg2dec/mpeg2decode -b ./src/mpeg2dec/input_base_4CIF_96bps.mpg -o3 ./src/mpeg2dec/output_base_4CIF_96bps_%03d
diplom:
cd src/mpeg2enc; make test
cd src/mpeg2dec; make test
#$(CC) $(CFLAGS) -o $@ -c $< 2> ./reportgcc-$<.lst
%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $< $(REPORTS)
profiling: profenc profdec
#profenc:
# ./src/mpeg2enc/mpeg2encode ./src/mpeg2enc/test.par ./src/mpeg2enc/new.m2v
# gprof ./src/mpeg2enc/mpeg2encode ./gmon.out > ./profiling/enc_profiling.txt
#profdec:
# ./src/mpeg2dec/mpeg2decode -f -b ./src/mpeg2enc/test.m2v
# gprof ./src/mpeg2dec/mpeg2decode ./gmon.out > ./profiling/dec_profiling.txt
profenc:
cd src/mpeg2enc; make profiling
profdec:
cd src/mpeg2dec; make profiling
Размещено на Allbest.ru
Подобные документы
Базовые инструменты Linux Shell и Make. Скриптовый язык Shell. Make как утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. Встраиваемые системы Buildroot и OpenWrt на базе Linux. Переменные и блоки define BuildPackage.
курсовая работа [27,4 K], добавлен 19.01.2016Разработка утилиты кодирования и декодирования формата Base 64 в программной среде Linux с использованием компилятора. Написание программы на языке С++. Кодирование символьной строки любого набора байт в последовательность печатных ASCII символов.
курсовая работа [1,4 M], добавлен 10.09.2013Разработка программы, предназначенной для сжатия или компрессии полутонового изображения международным стандартом JPEG. Описание метода JPEG, выдача результатов в виде декодированного изображения. Обзор методов компрессии полутонового изображения.
курсовая работа [43,5 K], добавлен 14.10.2012Понятие интегрированной логистики и ее главные направления развития на современном этапе. Виды автоматической идентификации, суть кодирования, достоинства и недостатки использование радиоволн (RFID), применение радиосканера, компьютера и радиометки.
контрольная работа [337,7 K], добавлен 27.09.2010Исследование методов оптимизации программного кода на языке Си с помощью компилятора. Тестирование результатов утилитой optbench.c. Определение особенностей оптимизации компилятора на собственной программе. Удачные примеры быстроты и компактности кода.
лабораторная работа [26,5 K], добавлен 17.12.2012Обзор электронного документа, его информационное содержание и виды. Разработка программы автоматической обработки текстовых материалов: выбор сред разработки, извлечение понятийной области, получение стека суждений. Стандарты кодирования информации.
дипломная работа [3,9 M], добавлен 10.05.2014Функции компилятора как системной обрабатывающей программы. Этапы компиляции: анализ и синтез. Разработка лексического анализатора. Алгоритм и программа лексического анализа. Реализация двухфазного компилятора. Описание логической структуры программы.
курсовая работа [310,4 K], добавлен 26.03.2010Методы арифметического кодирования. Основные функции программ, реализующие алгоритмы кодирования по методам Хаффмана, Голомба, Фибоначчи и Элиаса. Разработка программно-аппаратных средств оптимального арифметического кодирования и их экономический расчет.
дипломная работа [1,1 M], добавлен 26.05.2012Intel 8051 как 8-разрядный однокристальный микроконтроллер гардвардской архитектуры, впервые произведенный компанией Intel в 1980 году и предназначенный для использования во встраиваемых системах, его структура и функционал. Алгоритм работы программы.
контрольная работа [48,2 K], добавлен 04.03.2014Особенности кодирования информации с помощью метода Хаффмана. Реализация кодера и декодера с использованием статического алгоритма Хаффмана. Структура программы, оценка ее эффективности (степени сжатия) в зависимости от типа и размера сжимаемых файлов.
курсовая работа [136,2 K], добавлен 15.06.2013