Robi2810 / avs-idz-1

Итоговое домашнее задание 1 по АВС

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ИДЗ №1 Вариант 29

Амирханов Никита Русланович БПИ219

Условия

Сформировать массив B из произведения соседних элементов A по следующему правилу: B0=A0 * Am, B1=A1 * Am, ..., где m – либо номер первого четного отрицательного элемента массива А, либо номер последнего элемента, если в массиве А нет отрицательных элементов.

Задание решено на 10 баллов.

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

Структура папок

  • /asm содержит исходный код на ассембеле без использования си функций
  • /asm/lib содержит файлы с дополнительными функциями
    • array.s - работа с массивами
    • io.s - ввод/вывод из консоли/файлов
    • str.s - работа со строками
    • time.s - замер времени
    • rand.s - генерация случайных чисел
  • /asm/main.s - главный файл программы
  • /c-stuff содержит исходный код на языке си и результаты его компиляции
  • /tests папка с тестами
  • Файл make-tests.py позволяет создавать тесты необходимой длины

Запуск ассемблерного кода

make compile    ; компилирует все дополнительные библиотеки
make build      ; компилирует основой код с добавлением библиотек

Далее, чтобы запустить ручной ввод/вывод необходимо выполнить просто ./main. Для ввода и вывода в файл необходимо укзаать два аргумента ./main <input_file> <output_file>. Для работы с генератором случайных чисел необходимо набрать ./main -r <count> <lower_bound> <upper_bound> <output_file>. В таком случае на экран будет выведен сгенерированный массив. Во всех случаях ограничение на длину массива 100000000 элементов. При вводе большего числа будет выведено сообщение. Ограничения на сами элементы нет. Но если будут введены числа по модулю большие чем long то не гарантируется верный ответ.

Запуск си кода

gcc main.c -o main

В си программе отсутствует ручной ввод вывод. Для ввода и вывода необходимо укзаать два аргумента ./main <input_file> <output_file>. Для работы с генератором случайных чисел необходимо набрать ./main -r <count> <lower_bound> <upper_bound> <output_file>.

Важно

  • В папке tests нет тестов на 100000000 чисел из за большого размера файла.
  • Файлы которые подаются в вход программе должны содержать перенос строки в конце. Пример:
5
1
2
3
4
5

Работа с рандомайзером

В обоих случая надо при запуске указать параметры. Пример:

$ ./main -r 20 -20 20 out.txt
-1 -11 5 2 -20 2 3 -13 5 17 -20 15 18 -6 -13 9 0 0 20 20 
Elapsed time:  
Read:          0.0
Calculations:  0.239
Write:         0.92549

Выведется сгеренированный массив длиной 20 с значениями от -20 до 20, а в файл out.txt будет помещен результат выполнения.

Тестирование ASM

  • Обычный тест где нет четного отрицательного ./main ../tests/test1.txt out.txt
5
1
2
3
4
5

Результат

5
10
15
20
25

  • Обычный тест где есть четное отрицательное ./main ../tests/test2.txt out.txt
5
1
-2
3
4
5

Результат

-2
4
-6
-8
-10

  • Обычный тест где есть отрицательное но оно не четное ./main ../tests/test3.txt out.txt
5
1
-3
3
4
5

Результат

5
-15
15
20
25

Тестирование C

  • Обычный тест где нет четного отрицательного ./main ../tests/test1.txt out.txt
5
1
2
3
4
5

Результат

5
10
15
20
25

  • Обычный тест где есть четное отрицательное ./main ../tests/test2.txt out.txt
5
1
-2
3
4
5

Результат

-2
4
-6
-8
-10

  • Обычный тест где есть отрицательное но оно не четное ./main ../tests/test3.txt out.txt
5
1
-3
3
4
5

Результат

5
-15
15
20
25

Вывод тестирования

Результаты работы программ совпадают

Сравнение прогамм на си и asm

  1. Размер исполняемого файла
  • Размер ассемблероного файла сгенерированного из си кода при помощи флагов -masm=intel -fno-asynchronous-unwind-tables -fno-jump-tables -fno-stack-protector -fno-exceptions -Os составляет всего 243 строки. А с оптимизацией -Ofast 377 строк. В то же время размер самописной программы на ассемблере составляет 413 строк в main файле + 530 строк в вспомогательных файлах. Однако размер исполняемого файла на ассемблере составляет 7,1K а у программы на си 13K, а с флагом -Os тоже 13K.
  1. Время работы программ
  • Тестировалась работа программ написанных на ассемблере, на си, на ассемблероном коде, скомпилированным при помощи флага -Ofast, а так же при помощи флага -Os.
  • На тесте в 100000 элементов:
asm                         c:          -Ofast asm  -Os asm  
--------------------------------------------------------------
Read:          0.78601389   | 0.004616  | 0.004694  | 0.004389
Calculations:  0.263031     | 0.000126  | 0.000140  | 0.000115
Write:         0.287058676  | 0.004586  | 0.004624  | 0.003961
  • На тесте в 1000000 элементов:
asm:                        c:          -Ofast asm  -Os asm
-------------------------------------------------------------
Read:          0.727040354  | 0.044912  | 0.046473  | 0.045780
Calculations:  0.2503454    | 0.001279  | 0.001220  | 0.001285
Write:         2.433563873  | 0.044850  | 0.044344  | 0.041114
  • На тесте в 10000000 элементов:
asm:                        c:          -Ofast asm  -Os asm
--------------------------------------------------------------
Read:          7.362924217  | 0.508615  | 0.447636  | 0.439966
Calculations:  0.22556240   | 0.053719  | 0.010598  | 0.012137
Write:         25.433004001 | 0.516155  | 0.452513  | 0.442933
  • На тесте в 100000000 элементов:
asm:                        c:          -Ofast asm  -Os asm
-------------------------------------------------------------
Read:          72.466802783 | 5.043507  | 4.470650  | 4.498052
Calculations:  0.957936372  | 0.553682  | 0.136249  | 0.115879
Write:         256.506313724| 5.078061  | 4.506198  | 4.125936
  1. Обработка некорректных данных
  • Количество элементов больше 100000000
    • Обе программы выводят сообщение об ошибке Length is greater than 100000000!
  • Вводимые элементы не помещаются в long
    • В обоих случаях undefined behavior
  • Указанного файла не существует
    • Программа на си выводит сообщение с ошибкой, программа на ассемблере выведет сообщение об ошибке и укажет код ошибки Error while opening a file: 2. В данном случае 2 означает No such file or directory.

Вывод

Компилятор gcc осказался умнее меня. Скорость работы программы на чистом ассемблере оказалась меньше чем на си с разницей до 4-х раз. При этом время на операции ввода и вывода оказалось в среднем в 50 раз больше. Размер исполняемого файла на ассемблере оказлся меньше чем на си. При этом, написание когда на ассемблее во много раз дольше.

About

Итоговое домашнее задание 1 по АВС


Languages

Language:Assembly 92.9%Language:C 4.4%Language:Makefile 2.1%Language:Python 0.6%