GithubHelp home page GithubHelp logo

wentwrong / hashing-result Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 99 KB

Тестовое задание в Luxoft (сигнатура файла)

CMake 4.10% C++ 73.03% Go 22.87%
golang cpp multithreading

hashing-result's Introduction

  1. Постановка задачи Signature
  2. Структура проекта
  3. О задаче
  4. Алгоритмы параллельного решения
  5. Benchmark
  6. Выводы

Постановка задачи Signature

Требуется написать консольную программу на C++ для генерации сигнатуры указанного файла. Сигнатура генерируется следующим образом: исходный файл делится на блоки равной (фиксированной) длины (если размер файла не кратен размеру блока, последний фрагмент может быть меньше или дополнен нулями до размера полного блока). Для каждого блока вычисляется значение hash функции и дописывается в выходной файл-сигнатуру

Интерфейс: командная строка, в которой указаны:

  • Путь до входного файла
  • Путь до выходной файла
  • Размер блока (по умолчанию, 1 Мб)

Обязательные требования:

  • Следует максимально оптимизировать скорость работы утилиты с учетом работы в многопроцессорной среде
  • Нужно реализовать правильную обработку ошибок на основе эксепшенов
  • При работе с ресурсами нужно использовать умные указатели
  • Не допускается использовать сторонние библиотеки OpenMP, OpenCL, etc
  • Решение должно быть оригинальным (выполнено самостоятельно)

Допущения:

  • Размер входного файла может быть много больше размера доступной физической памяти (> 4 Гб)
  • В качестве хэш функции можно использовать любую хэш функцию (MD5, CRC и т.д.)

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

  • include/ - папка с заголовочными файлами
  • src/ - папка с исходными кодами
  • src/main.cpp - точка входа в программу
  • CMakeLists.txt - файл для cmake
  • hr-go.go - исходный код аналогичной программы на Golang (подробнее в разделе Benchmark)

С++17 стандарт только из-за использования std::filesystem::file_syze. Можно изменить способ измерения размера файла на различные костыли и код станет в соответствии с C++11.

Build проекта:

cmake .
make

Build Golang-решения:

go build hr-go.go

О задаче

  • В качестве хэш-функции я использовал CRC32. Таким образом, выбором некриптостойкой хеш-функции, предполагается вычисление контрольной суммы данных, полученных из доверенного источника.
  • Каждое хэш-значение я записывал в конец выходного файла в формате 4-байтного числа, таким образом тратя 10 байт (можно было бы всерьёз сэкономить, если вместо ASCII-значений цифр числа записывать прямо его 4 байтовое значение). Т.е. вместо CRC32("FOO") = "0450111403" записывать 4 байта 0x1AD427AB
  • Хэш-функцию я скопипастил дабы соответствовать пункту о запрете сторонних библиотек. Иначе пришлось бы тянуть с собой Boost, OpenSSL или ещё что-то (что было бы сделать более правильно, поскольку это криптография)
  • Более подходящим инструментом для решения этой задачи было бы использовать Golang.

Алгоритмы параллельного решения

Моё решение

Создаём N потоков, каждый из которых выполняет следующий цикл:

  • Получить уникальное смещение;
  • Прочитать из входного файла блок данных по смещению;
  • Посчитать хэш-значение от блока данных;
  • Записать в выходной файл по смещению.

Моя версия

Более правильный и более сложный для реализации

  • Один поток читает из входного файла и помещает блоки в буфер;
  • Потоки из Thread Pool: берут из буфера блок, считают хэш-значение, помещают в другой буфер;
  • Ещё один поток считывает данные из буфера с хэшами и записывает в выходной файл.

Более архитектурно верное

Benchmark

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

  • ./hr - моё предыдущее однопоточное решение
  • ./hrmt - нынешнее многопоточное решение
  • ./hr-go - многопоточное решение на Golang.

Все тесты производительности делались при помощи Hyperfine. Все нижеописанные результаты получены при помощи 30 запусков. Вот такой командой:

hyperfine -r 30 --export-markdown md.md './hr input output_1' './hrmt input output_2' './hr-go input output_3'

(после этого я сравнивал md5sum output_* полученных файлов, всё сходилось)

  • входной файл - файл размером 1 Гбайт (GiB, 2^30 байт)
  • размер блока - 1 Мбайт (MiB, 2^20 байт)
Command Mean [s] Min [s] Max [s] Relative
./hr input output_1 3.896 ± 0.009 3.883 3.927 5.46 ± 0.10
./hrmt input output_2 1.941 ± 0.012 1.930 1.990 2.72 ± 0.05
./hr-go input output_3 0.714 ± 0.013 0.688 0.738 1.00
  • входной файл - файл размером 5 Гбайт
  • размер блока - 1 Мбайт
Command Mean [s] Min [s] Max [s] Relative
./hr input output_1 19.469 ± 0.045 19.394 19.521 5.51 ± 0.05
./hrmt input output_2 9.696 ± 0.033 9.646 9.772 2.74 ± 0.02
./hr-go input output_3 3.536 ± 0.029 3.483 3.591 1.00
  • входной файл - файл размером 1 Гбайт
  • размер блока - 100 Мбайт
Command Mean [s] Min [s] Max [s] Relative
./hr input output_1 104857600 4.489 ± 0.318 4.416 6.174 8.31 ± 3.04
./hrmt input output_2 104857600 2.178 ± 0.010 2.169 2.209 4.03 ± 1.45
./hr-go input output_3 104857600 0.540 ± 0.194 0.477 1.313 1.00

Выводы

По результатам тестов, в сравнении с предыдущим однопоточным решением, многопоточное запускается в ~2 раза быстрее, что объясняется тем, что запуски производились на двухядерном процессоре. На машине с большим количеством вычислительной мощи, можно ожидать кратного количеству ядер процессора эффекта увеличения скорости программы (до того как всё упрётся в I/O bounds).

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

hashing-result's People

Contributors

wentwrong avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.