2013-10-24 2 views
8

Я работаю с таблицами хэша, и я наткнулся на эту функцию. Но что означает hash/sizeof (void *)? и комментарий после него - избавиться от известных-0 бит?Что означает разделение на sizeof (void *)?

// This matches when the hashtable key is a pointer. 
     template<class HashKey> class hash_munger<HashKey*> { 
     public: 
     static size_t MungedHash(size_t hash) { 
      // TODO(csilvers): consider rotating instead: 
      // static const int shift = (sizeof(void *) == 4) ? 2 : 3; 
      // return (hash << (sizeof(hash) * 8) - shift)) | (hash >> shift); 
      // This matters if we ever change sparse/dense_hash_* to compare 
      // hashes before comparing actual values. It's speedy on x86. 
      return hash/sizeof(void*); // get rid of known-0 bits 
     } 
     }; 
+1

Похоже на [вы не должны это понимать] (http://cm.bell-labs.com/cm/cs/who/dmr/odd.html) комментарий. –

ответ

9

На большинстве машин и ABIs, указатели, как правило, слово выровнены. Таким образом, деление на указатели sizeof по существу игнорирует наименьшие биты (например, 3 младших бита байтовых адресов равны 0 на большинстве 64-битных процессоров, поскольку 64-битное слово имеет 8 байтов, каждый из 8 бит).

+0

Что такое ABI? И, выровненный по слову, вы имеете в виду, что они смежно хранятся в памяти? – annunarcist

+0

Я добавил ссылку на wikipage на ABI. –

+1

@annunarcist: Нет, выравнивание и непрерывное хранение почти полностью не связаны. В C++ массивы всегда смежны независимо от выравнивания, но другие объекты могут быть не смежными. – MSalters

2

Похоже, что это функция хэширования указателя. Указатели указывают на объекты, которые часто выравниваются. Если объект, на который указывает объект, выделяется «новым», он, скорее всего, будет привязан к границе слова.

Следовательно, он может быть всегда делимым на 8 (или 4, если это размер слова) (при преобразовании в число), и функция делит ваш номер на 8, чтобы дать вам то, что действительно важно относительно вашего указателя ,