В данном проекте я реализовал хэш-таблицу закрытого типа и оптимизоировал её с помощью ассемблерных вставок/интринсиков/ассемблерных функций
Написав хэш-таблицу, я измерил время, используемое каждой из функций с помощью callgrind.
Получились следующие результаты:
Т.к. мы всё-таки делаем ХЭШ-функцию, в первую очередь я решил оптимизировать хэш.
Я знал длину каждого слова, поэтому была придумана оптимизация с названием "Жадный crc", в ней я по максимуму хэшурую слово частями по 8 байт, а после добираю остаток.
После первой оптимизации я был удивлён тем, что общее время работы программы не изменилось, поэтому я снова решил обратиться к callgrind
И что же я получил:
Несложно понять, что, оказывается, узким местом моей программы являлась фунция main.
Что ж... Проанализировав код данной функции, я понял, что я трачу слишком много времени, сканируя из буффера по 1 байту, поэтому я решил сканировать сразу по 32 байта с помощью avx2 инструций!!!
А после с помощью битовой магии я начал доставать по 1 слову из буфера, то есть вместо 1 символа за итерацию for'а я обрабатываю по целому слову.
Судя по этим замечательным результатам, оптимизация фунции main прошла успешно, время выполнения программы уменьшилось в полтора раза, но из-за битовых операций нам потребовалось брать двоичный логарифм числа, который я брал с помощью for'ика, перебирая биты от 0 до 31.
Но моя реализация слишком много времени, поэтому я начал искать соответствующую инструцию процессора, и я её нашёл - это bsr!
После всех этих оптимизаций я очень хотел поскорее узнать результат. И инструкция bsr сработала великолепно! Время выполнения программы относительно первой реализации уменьшилось в 2.5 раза!
Как мы видим, узким местом программы снова стал хэш, но дальнейшая оптимизация не так и нужна...
Также хочется показать вам результаты тестирования нескольких хэш-функций, по оси X вы можете наблюдать индекс хэша в хэш-таблице, а по оси Y - количество коллизий.
H1: Всегда возвращаем 1 H2: Возвращаем код первого ascii символа слова H3: Возвразаем длину слова H4: Возвращаем сумму ascii кодов слова H5: H_0 = s[0]; H_i = rol(H_{i-1}) + s[i] H6: crc32