Pull to refresh

Comments 9

Хеш функция вместо того чтобы считать каждую букву строки, просто кастит указатель на данные строки к uint64_t keyArray[3] и считает сумму целых чисел.

… и вылетает по ошибке «доступ к невыровненной памяти» на процессоре ARM.
так компилятор же вполне способен положить строки с выравниванием по 8 байт. Если только специально не размещать их невыровненными, проблем не будет.
Компилятор-то тут при чем? Строки — это часть стандартной библиотеки. А стандарт не дает никаких гарантий того, что адрес начала строки будет выровнен (в стандарте С++11 это раздел 21.4.7.1 basic_string accessors [string.accessors]).
Если же вы об ASCIIZ-строках, то да, можно выравнивать их через прагмы, атрибуты или опции компилятора, но зачем?

ADD: Кроме того, подразумевается, что «быстрый хэш» будет использоваться как библиотека. Требовать от пользователя, чтобы все строки были выровнены на границу 8 байт — это перебор.
Хм, железке DMA-контроллеру, значит, от меня можно требовать, а автору библиотеки — нет?! Дискриминационненько как-то… ))))
Ну, например, иногда при парсинге json-файла в целях ускорения работы вместо выделения памяти под каждую найденную строковую константу просто записывается '\0' на месте закрывающей кавычки и используется указатель на адрес начала подстроки. Или, например, схожим образом работает lazy_bdecode в libtorrent (но там используется указатель на начало и длина, по которым в случае необходимости создается std::string). Так что кейс довольно популярный на самом деле.
во-первых, если говорить именно про std::string, то выравнивание буфера зависит от реализации аллокатора, но едва ли оно будет меньше 8 байт. Во-вторых, речь в статье не о хеш-функции (взятой, судя по всему, от балды), а об алгоритме кеширования. Эти вещи практически невисимы (производительность алгоритма кеширования может падать в случае плохой хеш-функции).
во-первых, если говорить именно про std::string, то выравнивание буфера зависит от реализации аллокатора, но едва ли оно будет меньше 8 байт.

Закладываться на особенности конкретной реализации — это прямой путь к большим проблемам в будущем.

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

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

Друзья,
спасибо за активную переписку, которая навела меня на понимание сути ваших сомнений.
Вчера просто утром увидел коммент про проблемы на ARM процессорах (а такие у меня только на телефонах с Android есть), и решил сочетая полезное с полезным поднять стенд для Android (https://github.com/DimaBond174/android_cache — тут пока ещё только заголовок).


Вот, сегодня утром прочитал комментарии… и отвечаю:
Поведение ключа будь то числовой, строковый (или по музыке/видео/изображению/неведомому сферическому коню в вакууме) — это не вопрос библиотеки кеширования. Библиотеке кеширования (которая шаблон в одном .h файле) просто требуется от ключа реализация функций inline int compare (...) и inline uint64_t get_hash(...).


То как ключ себя ведёт со строками — частное личное внутреннее дело ключа и алгоритму кеширования до него дела нет. В частности предложенный расчёт хэш-а строки по uint64_t[3] в файле ikey2.h реализован так что при установке в ключ строки вызывается метод который гарантирует расширение строки до требуемого размера:


static constexpr int key_ElemNSizeKey_size = 3 * sizeof(uint64_t);
    void setKey() {
      len = data.length();
      if (data.capacity()  <  key_ElemNSizeKey_size)  {
        data.reserve(key_ElemNSizeKey_size);
      }
      key.setKey(data.data());
    }

Если по каким-либо причинам компилятор решит оптимизировать расширение строки, то всегда можно сделать memcpy в обнулённый массив uint64_t[3] на минимальное
из текущего размера строки и key_ElemNSizeKey_size.

Друзья, я протестировал строковые ключи на Android, ARM процессор — всё работает замечательно:
Sign up to leave a comment.

Articles

Change theme settings