Amogh Margoor has uploaded a new patch set (#12). ( http://gerrit.cloudera.org:8080/17592 )
Change subject: IMPALA-7635: Reducing HashTable size by packing it's buckets efficiently. ...................................................................... IMPALA-7635: Reducing HashTable size by packing it's buckets efficiently. HashTable implementation in Impala comprises of contiguous array of Buckets and each Bucket contains either data or pointer to linked list of duplicate entries named DuplicateNode. These are the structures of Bucket and DuplicateNode: struct DuplicateNode { bool matched; DuplicateNode* next; HtData htdata; }; struct Bucket { bool filled; bool matched; bool hasDuplicates; uint32_t hash; union { HtData htdata; DuplicateNode* duplicates; } bucketData; }; Size of Bucket is currently 16 bytes and size of DuplicateNode is 24 bytes. If we can remove the booleans from both struct size of Bucket would reduce to 12 bytes and DuplicateNode will be 16 bytes. One of the ways we can remove booleans is to fold it into pointers already part of struct. Pointers store addresses and on architectures like x86 and ARM the linear address is only 48 bits long. With level 5 paging Intel is planning to expand it to 57-bit long which means we can use most significant 7 bits i.e., 58 to 64 bits to store these booleans. This patch reduces the size of Bucket and DuplicateNode by implementing this folding. However, there is another requirement regarding Size of Bucket to be power of 2 and also for the number of buckets in Hash table to be power of 2. These requirements are for the following reasons: 1. Memory Allocator allocates memory in power of 2 to avoid internal fragmentation. Hence, num of buckets * sizeof(Buckets) should be power of 2. 2. Number of buckets being power of 2 enables faster modulo operation i.e., instead of slow modulo: (hash % N), faster (hash & (N-1)) can be used. Due to this, 4 bytes 'hash' field from Bucket is removed and stored separately in new array hash_array_ in HashTable. This ensures sizeof(Bucket) is 8 which is power of 2. New Classes: ------------ As a part of patch, TaggedPointer is introduced which is a template class to store a pointer and 7-bit tag together in 64 bit integer. This structure contains the ownership of the pointer and will take care of allocation and deallocation of the object being pointed to. However derived classes can opt out of the ownership of the object and let the client manage it. It's derived classes for Bucket and DuplicateNode do the same. These classes are TaggedBucketData and TaggedDuplicateNode. Benchmark: ---------- As a part of this patch a new Micro Benchmark for HashTable has been introduced, which will help in measuring these: 1. Runtime for building hash table and probing it. 2. Memory consumed after building the Table. This would help measuring the impact of changes to the HashTable's data structure and algorithm. Saw 25-30% reduction in memory consumed and no significant difference in performance (0.91X-1.2X). Other Benchmarks: 1. Billion row Synthetic benchmark on single node, single daemon: a. 2-3% improvement in Join GEOMEAN for Probe benchmark. b. 17% and 21% reduction in PeakMemoryUsage and CumulativeBytes allocated respectively 2. TPCH-42: 0-1.5% improvement in GEOMEAN runtime Change-Id: I72912ae9353b0d567a976ca712d2d193e035df9b --- M be/src/benchmarks/CMakeLists.txt A be/src/benchmarks/hash-table-benchmark.cc M be/src/exec/grouping-aggregator-ir.cc M be/src/exec/grouping-aggregator-partition.cc M be/src/exec/grouping-aggregator.cc M be/src/exec/hash-table-test.cc M be/src/exec/hash-table.cc M be/src/exec/hash-table.h M be/src/exec/hash-table.inline.h M be/src/util/CMakeLists.txt M be/src/util/benchmark.cc M be/src/util/benchmark.h A be/src/util/tagged-ptr-test.cc A be/src/util/tagged-ptr.h M fe/src/main/java/org/apache/impala/planner/PlannerContext.java M fe/src/test/java/org/apache/impala/planner/CardinalityTest.java M testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection-hdfs-num-rows-est-enabled.test M testdata/workloads/functional-planner/queries/PlannerTest/fk-pk-join-detection.test M testdata/workloads/functional-planner/queries/PlannerTest/max-row-size.test M testdata/workloads/functional-planner/queries/PlannerTest/resource-requirements.test M testdata/workloads/functional-planner/queries/PlannerTest/spillable-buffer-sizing.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q01.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q04.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q05.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q06.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q07.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q11.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q12.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q14a.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q15.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q16.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q17.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q18.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q19.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q20.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q22.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q23a.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q23b.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q24a.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q24b.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q25.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q26.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q27.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q29.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q34.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q35a.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q38.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q39a.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q39b.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q45.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q46.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q47.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q48.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q50.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q51.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q56.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q57.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q58.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q60.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q61.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q64.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q66.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q67.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q68.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q72.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q73.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q74.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q78.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q80.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q82.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q83.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q85.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q87.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q95.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q97.test M testdata/workloads/functional-planner/queries/PlannerTest/tpcds/tpcds-q98.test M testdata/workloads/functional-planner/queries/PlannerTest/tpch-all.test M testdata/workloads/functional-planner/queries/PlannerTest/tpch-kudu.test M testdata/workloads/functional-planner/queries/PlannerTest/tpch-nested.test M testdata/workloads/functional-query/queries/QueryTest/spilling-broadcast-joins.test M testdata/workloads/functional-query/queries/QueryTest/spilling.test 81 files changed, 1,972 insertions(+), 1,048 deletions(-) git pull ssh://gerrit.cloudera.org:29418/Impala-ASF refs/changes/92/17592/12 -- To view, visit http://gerrit.cloudera.org:8080/17592 To unsubscribe, visit http://gerrit.cloudera.org:8080/settings Gerrit-Project: Impala-ASF Gerrit-Branch: master Gerrit-MessageType: newpatchset Gerrit-Change-Id: I72912ae9353b0d567a976ca712d2d193e035df9b Gerrit-Change-Number: 17592 Gerrit-PatchSet: 12 Gerrit-Owner: Amogh Margoor <amarg...@gmail.com> Gerrit-Reviewer: Amogh Margoor <amarg...@gmail.com> Gerrit-Reviewer: Impala Public Jenkins <impala-public-jenk...@cloudera.com> Gerrit-Reviewer: Joe McDonnell <joemcdonn...@cloudera.com> Gerrit-Reviewer: Qifan Chen <qc...@cloudera.com> Gerrit-Reviewer: Zoltan Borok-Nagy <borokna...@cloudera.com>