From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by sourceware.org (Postfix) with ESMTPS id BC5313858C41; Thu, 18 Jan 2024 09:26:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BC5313858C41 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BC5313858C41 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::831 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705569984; cv=none; b=YrNxdqA47n0EA1m4uUR0jORemHcIYujMbPqb/5UD/LAPjW9UGzRx1drGpYzAiUuazpGbV09+ICqsRRql8ARc6/vuqLSXTnpWqlIK9PMBw2cI05+Mn40w7yuVuDBwCy/3BxplyvFJh6KOBa+kWNeGg8Oys8yQF2aIyN6hTHRb/f4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705569984; c=relaxed/simple; bh=8wvN+tMnp+/HqsWWRoG5iHfy3zMqdnCYnjxcCFnEOZw=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=aPOIvFl72ZWAPGKO+7D6hPQCAx9cregX9PcoKfgZ3l4Lv/2tRmbOSosFxavFTqD+R6CwAXLIdpmXAxKYvY6tYPsE0Ap8uQ8CJIyGtbMhFEzUW9fWcAOtONPPrQTbo9DJW2Q5o+Xiw99mC2BwnBMgtnIgsS7+f/BN8DdEP052ldw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-qt1-x831.google.com with SMTP id d75a77b69052e-429dd92b842so41718781cf.3; Thu, 18 Jan 2024 01:26:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705569980; x=1706174780; darn=gcc.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=oP08k7Sv+jjyX/wMEPOjyanxK0cWJYaWPOmHbBqcwoY=; b=hponI91mMOlgstyHqex3XfUDGFs4z1t+jAeVrccjUeOS6FVw230OnlHiase3w6l8rc vH6l/hm3XVVrADnDSUzRShJr3FVrxrmVIZzaiWUJLtUbthZLOmT9+Yeqfe+xfWlxPmQ1 zb46eGAcwXDVeBDH3cwzFB6JYU22hJz5JBB4/dViGaBqLAYmN73Dnq8hqMty5Zyo7iJa D9Tr5duHoawmA+84ZhZlQTf3dc2CuBsxdL0iUKv6OTtCy6JMlIgzS2kl7czri7WumBgC Cy1CWXSNHDR5DYaLQf2kztc53j6lEM1Ne6ozVz1fJAfIfDpOTbzTZsmKQAWa88eP7YE/ q/jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705569980; x=1706174780; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=oP08k7Sv+jjyX/wMEPOjyanxK0cWJYaWPOmHbBqcwoY=; b=sxNjyRHih6HN5xTadkXLrIdG+fkwa7QgeieYSdN9jK56Bi92NVx/0+1Lq1k2Fm8+l8 lEX5U+oAVnnxIyTbaDRersFIQSuL9Ck4QRvvHLF5v94v9X+wG03coHhYNA8ooOoYPWmX IxEVHcSxHpB8oZV/5oTq+/2brVva/WLohyIupzEMslekK9JGTHBYMaj9t3EMHZ9pw+98 TtFROD8+/J2Z+ahPcEGugqr9x3cGU06utSC/U2/oLU6GCktm7Gou/RO2t4OEiPTFb3t5 Rl177cNS4ogPqWQtODHzQpFDS4WibSxMmfCTW7yQbxP993HYhxNVlx9BT/QPge3MH1Ka 9L5A== X-Gm-Message-State: AOJu0YxNdYqcpTLsxVETlQ8tVVkIk8UMjyYMEnyCkpIGXF2mzuSK9Bvk BrdVE4JbxagYZYkIdpbzgz+0D/pcH+h6+MH5kVK7l5HqPBIXH7ej89jRW59qYhVfMvkqUUoGBk7 o/+tbzor708qbiaIhfRbrG8jSReiimun6Vr1RJJz+7dI= X-Google-Smtp-Source: AGHT+IFBVBuVieSpFxqVHxDbEowUaSElxzhlvbqTXfk2Ig8G9jw5qWqS568lGYDgBRUw94NqXSvyk6yuqJ8bemnLLZM= X-Received: by 2002:ac8:5d12:0:b0:429:a83a:f6b8 with SMTP id f18-20020ac85d12000000b00429a83af6b8mr639912qtx.47.1705569980013; Thu, 18 Jan 2024 01:26:20 -0800 (PST) MIME-Version: 1.0 References: <5b87ddea-ba56-4173-bda3-652f038dcacc@gmail.com> In-Reply-To: <5b87ddea-ba56-4173-bda3-652f038dcacc@gmail.com> From: Huanghui Nie Date: Thu, 18 Jan 2024 17:26:08 +0800 Message-ID: Subject: Re: [PATCH] libstdc++: hashtable: No need to update before begin node in _M_remove_bucket_begin To: =?UTF-8?Q?Fran=C3=A7ois_Dumont?= Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Content-Type: multipart/mixed; boundary="000000000000cc97ad060f34f44e" X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,HK_RANDOM_ENVFROM,HK_RANDOM_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --000000000000cc97ad060f34f44e Content-Type: multipart/alternative; boundary="000000000000cc97aa060f34f44c" --000000000000cc97aa060f34f44c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Yes, I have. I did a benchmark today. The conclusion is: the time consumption can be reduced by 0.4% ~ 1.2% when unordered_set erase(begin()), and 1.2% ~ 2.4% when erase(begin(), end()). My test environment: CPU: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz, 2393.365 MHz, 56 CPUs MEM: 256G OS: CentOS-8.2 g++: gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) Compile flags: -O3 -std=3Dc++17 Test conclusion data (time taken to delete every 100 million elements): erase(begin()): |size of unordered_set |100 |1,000 |10,000 |100,000 |1,000,000|10,000,000| |base time consuming (ms)|3827.736|3807.725|3830.168|3807.373|3798.713 |3854.168 | |test time consuming (ms)|3783.406|3789.460|3791.146|3778.033|3783.494 |3808.137 | |Time-consuming reduction|1.16% |0.48% |1.02% |0.77% |0.40% |1.1= 9% | erase(begin(),end()): |size of unordered_set |100 |1,000 |10,000 |100,000 |1,000,000|10,000,000| |base time consuming (ms)|2779.229|2768.550|2795.778|2767.385|2761.521 |2804.099 | |test time consuming (ms)|2712.759|2726.578|2752.224|2732.140|2718.953 |2739.727 | |Time-consuming reduction|2.39% |1.52% |1.56% |1.27% |1.54% |2.3= 0% | Please see the attachment for test code and detailed test result. 2024=E5=B9=B41=E6=9C=8818=E6=97=A5(=E6=9C=A8) 4:04 Fran=C3=A7ois Dumont : > Hi > > Looks like a great finding to me, this is indeed a useless check, thanks! > > Have you any figures on the performance enhancement ? It might help to get > proper approval as gcc is currently in dev stage 4 that is to say only bug > fixes normally. > > Fran=C3=A7ois > On 17/01/2024 09:11, Huanghui Nie wrote: > > Hi. > > When I implemented a hash table with reference to the C++ STL, I found > that when the hash table in the C++ STL deletes elements, if the first > element deleted is the begin element, the before begin node is repeatedly > assigned. This creates unnecessary performance overhead. > > > First, let=E2=80=99s see the code implementation: > > In _M_remove_bucket_begin, _M_before_begin._M_nxt is assigned when > &_M_before_begin =3D=3D _M_buckets[__bkt]. That also means > _M_buckets[__bkt]->_M_nxt is assigned under some conditions. > > _M_remove_bucket_begin is called by _M_erase and _M_extract_node: > > 1. Case _M_erase a range: _M_remove_bucket_begin is called in a for > loop when __is_bucket_begin is true. And if __is_bucket_begin is true = and > &_M_before_begin =3D=3D _M_buckets[__bkt], __prev_n must be &_M_before= _begin. > __prev_n->_M_nxt is always assigned in _M_erase. That means > _M_before_begin._M_nxt is always assigned, if _M_remove_bucket_begin is > called and &_M_before_begin =3D=3D _M_buckets[__bkt]. So there=E2=80= =99s no need to > assign _M_before_begin._M_nxt in _M_remove_bucket_begin. > 2. Other cases: _M_remove_bucket_begin is called when __prev_n =3D=3D > _M_buckets[__bkt]. And __prev_n->_M_nxt is always assigned in _M_erase= and > _M_before_begin. That means _M_buckets[__bkt]->_M_nxt is always assign= ed. > So there's no need to assign _M_buckets[__bkt]->_M_nxt in > _M_remove_bucket_begin. > > In summary, there=E2=80=99s no need to check &_M_before_begin =3D=3D _M_b= uckets[__bkt] > and assign _M_before_begin._M_nxt in _M_remove_bucket_begin. > > > Then let=E2=80=99s see the responsibility of each method: > > The hash table in the C++ STL is composed of hash buckets and a node list. > The update of the node list is responsible for _M_erase and _M_extract_no= de > method. _M_remove_bucket_begin method only needs to update the hash > buckets. The update of _M_before_begin belongs to the update of the node > list. So _M_remove_bucket_begin doesn=E2=80=99t need to update _M_before_= begin. > > > Existing tests listed below cover this change: > > 23_containers/unordered_set/allocator/copy.cc > > 23_containers/unordered_set/allocator/copy_assign.cc > > 23_containers/unordered_set/allocator/move.cc > > 23_containers/unordered_set/allocator/move_assign.cc > > 23_containers/unordered_set/allocator/swap.cc > > 23_containers/unordered_set/erase/1.cc > > 23_containers/unordered_set/erase/24061-set.cc > > 23_containers/unordered_set/modifiers/extract.cc > > 23_containers/unordered_set/operations/count.cc > > 23_containers/unordered_set/requirements/exception/basic.cc > > 23_containers/unordered_map/allocator/copy.cc > > 23_containers/unordered_map/allocator/copy_assign.cc > > 23_containers/unordered_map/allocator/move.cc > > 23_containers/unordered_map/allocator/move_assign.cc > > 23_containers/unordered_map/allocator/swap.cc > > 23_containers/unordered_map/erase/1.cc > > 23_containers/unordered_map/erase/24061-map.cc > > 23_containers/unordered_map/modifiers/extract.cc > > 23_containers/unordered_map/modifiers/move_assign.cc > > 23_containers/unordered_map/operations/count.cc > > 23_containers/unordered_map/requirements/exception/basic.cc > > > Regression tested on x86_64-pc-linux-gnu. Is it OK to commit? > > > --- > > ChangeLog: > > > libstdc++: hashtable: No need to update before begin node in > _M_remove_bucket_begin > > > 2024-01-16 Huanghui Nie > > > gcc/ > > * libstdc++-v3/include/bits/hashtable.h > > > --- > > > diff --git a/libstdc++-v3/include/bits/hashtable.h > b/libstdc++-v3/include/bits/hashtable.h > > index b48610036fa..6056639e663 100644 > > --- a/libstdc++-v3/include/bits/hashtable.h > > +++ b/libstdc++-v3/include/bits/hashtable.h > > @@ -872,13 +872,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > if (!__next_n || __next_bkt !=3D __bkt) > > { > > // Bucket is now empty > > - // First update next bucket if any > > + // Update next bucket if any > > if (__next_n) > > _M_buckets[__next_bkt] =3D _M_buckets[__bkt]; > > > > - // Second update before begin node if necessary > > - if (&_M_before_begin =3D=3D _M_buckets[__bkt]) > > - _M_before_begin._M_nxt =3D __next_n; > > _M_buckets[__bkt] =3D nullptr; > > } > > } > > --000000000000cc97aa060f34f44c-- --000000000000cc97ad060f34f44e Content-Type: application/octet-stream; name="test1.cc" Content-Disposition: attachment; filename="test1.cc" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lrizz0sq0 I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRl IDx1bm9yZGVyZWRfc2V0PgojaW5jbHVkZSA8Y2hyb25vPgoKaW50IG1haW4o aW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgaW50IHNpemUgPSA6OmF0b2ko YXJndlsxXSk7CiAgaW50IGxvb3AgPSA6OmF0b2koYXJndlsyXSk7CgogIHN0 ZDo6dW5vcmRlcmVkX3NldDxpbnQ+IGRhdGE7CiAgZGF0YS5yZXNlcnZlKHNp emUpOwogIGRvdWJsZSB0OwogIGZvciAoaW50IGsgPSAwOyBrIDwgbG9vcDsg KytrKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgewog ICAgICBkYXRhLmVtcGxhY2UoaSk7CiAgICB9CiAgICBhdXRvIHQxID0gc3Rk OjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCk7CiAgICBmb3IgKGludCBp ID0gMDsgaSA8IHNpemU7ICsraSkgewogICAgICBkYXRhLmVyYXNlKGRhdGEu YmVnaW4oKSk7CiAgICB9CiAgICBhdXRvIHQyID0gc3RkOjpjaHJvbm86OnN0 ZWFkeV9jbG9jazo6bm93KCk7CiAgICB0ICs9IHN0ZDo6Y2hyb25vOjpkdXJh dGlvbjxkb3VibGUsIHN0ZDo6bWljcm8+KHQyIC0gdDEpLmNvdW50KCk7CiAg fQogIHByaW50ZigiQ29zdDogJWxmXG4iLCB0KTsKICByZXR1cm4gMDsKfQoK --000000000000cc97ad060f34f44e Content-Type: application/octet-stream; name="test2.cc" Content-Disposition: attachment; filename="test2.cc" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lrizz7551 I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRl IDx1bm9yZGVyZWRfc2V0PgojaW5jbHVkZSA8Y2hyb25vPgoKaW50IG1haW4o aW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgaW50IHNpemUgPSA6OmF0b2ko YXJndlsxXSk7CiAgaW50IGxvb3AgPSA6OmF0b2koYXJndlsyXSk7CgogIHN0 ZDo6dW5vcmRlcmVkX3NldDxpbnQ+IGRhdGE7CiAgZGF0YS5yZXNlcnZlKHNp emUpOwogIGRvdWJsZSB0OwogIGZvciAoaW50IGsgPSAwOyBrIDwgbG9vcDsg KytrKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgewog ICAgICBkYXRhLmVtcGxhY2UoaSk7CiAgICB9CiAgICBhdXRvIHQxID0gc3Rk OjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCk7CiAgICBkYXRhLmVyYXNl KGRhdGEuYmVnaW4oKSwgZGF0YS5lbmQoKSk7CiAgICBhdXRvIHQyID0gc3Rk OjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCk7CiAgICB0ICs9IHN0ZDo6 Y2hyb25vOjpkdXJhdGlvbjxkb3VibGUsIHN0ZDo6bWljcm8+KHQyIC0gdDEp LmNvdW50KCk7CiAgfQogIHByaW50ZigiQ29zdDogJWxmXG4iLCB0KTsKICBy ZXR1cm4gMDsKfQoK --000000000000cc97ad060f34f44e Content-Type: text/csv; charset="US-ASCII"; name="result.csv" Content-Disposition: attachment; filename="result.csv" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lrj09eq72 aGFzaHRhYmxlIHZlcnNpb24sInRlc3QgdHlwZSgxPWVyYXNlKGJlZ2luKCkg Mj1lcmFzZShiZWdpbigpLCBlbmQoKSkiLHNpemUgb2YgdW5vcmRlcmVkX3Nl dCxsb29wLGNvc3QgdGltZTEsY29zdCB0aW1lMixjb3N0IHRpbWUzLGNvc3Qg dGltZTQsY29zdCB0aW1lNSxjb3N0IHRpbWU2LGNvc3QgdGltZTcsY29zdCB0 aW1lOCxjb3N0IHRpbWU5LGNvc3QgdGltZTEwLGNvc3QgdGltZTExLGNvc3Qg dGltZTEyLGNvc3QgdGltZTEzLGNvc3QgdGltZTE0LGNvc3QgdGltZTE1LGNv c3QgdGltZTE2LGNvc3QgdGltZTE3LGNvc3QgdGltZTE4LGNvc3QgdGltZTE5 LGNvc3QgdGltZTIwLGNvc3QgdGltZTIxLGNvc3QgdGltZTIyLGNvc3QgdGlt ZTIzLGNvc3QgdGltZTI0LGF2ZXJhZ2UgY29zdHRpbWUNCmJhc2UsMSwxMDAs MTAwMDAwMCwzODIzLjQ5MywzODIyLjY4MSwzODIzLjQ4NywzODI2LjAwOSwz ODI3LjQxOSwzODE1LjA0MywzODI0LjU3NiwzODI3LjU4NywzODIzLjExNSwz ODIyLjYyNSwzODI4LjQyMiwzODIzLjA1OCwzODI2LjU0OSwzODczLjgwNiwz ODE1LjY1NSwzODUzLjc3MywzODE2LjUxMiwzODI2LjM3MiwzODA3LjkzMiwz ODUyLjA2NywzODIwLjc1OSwzODI0LjAzNSwzODMzLjA3NywzODI3LjYxNiwz ODI3LjczNg0KdGVzdCwxLDEwMCwxMDAwMDAwLDM3NzEuNTcxLDM3NjkuMjQ1 LDM3ODQuMjU5LDM3NzAuMzU2LDM3OTkuNDEyLDM3NzMuOTQ2LDM4MTEuNTY0 LDM3NzAuOTIxLDM3NzYuOTg4LDM4MTQuMDc2LDM3ODIuOTUsMzc5Ni45ODQs Mzc3MC4wNDIsMzc4My45MzQsMzgyMi42MTQsMzc4Ni45ODYsMzc5OS45NDIs Mzc2OS43ODMsMzc3MS45NTQsMzc2Ny44NTYsMzc3MS43MSwzNzcxLjQsMzc4 Ny41ODQsMzc3NS42NzQsMzc4My40MDYNCmJhc2UsMiwxMDAsMTAwMDAwMCwy ODA5LjM4OSwyNzc4LjIwNiwyNzc2Ljc4MywyODA2LjQ2LDI3NzMuMjk3LDI3 NTMuODY4LDI3NzkuMDEsMjc4Mi43MTUsMjgwMS43NTgsMjc3Ni40NzUsMjc3 NS42MiwyNzg2LjE4MSwyNzcyLjg2NiwyNzc5LjE3MSwyNzc2LjcwNCwyNzc5 Ljc5LDI3NzguNzU2LDI3ODAuNTQ0LDI3ODMuNjM3LDI3NTQuNDIzLDI3ODAu MDIxLDI3NzguMTUyLDI3NTguMzksMjc3OS4yODksMjc3OS4yMjkNCnRlc3Qs MiwxMDAsMTAwMDAwMCwyNjk1Ljk5LDI3MDYuMTYzLDI3NDEuMDc0LDI3MDIu MTgxLDI3MTEuMDM5LDI2OTcuNjMzLDI3MDYuOTcyLDI3MzQuNzc2LDI3MDUu NTM5LDI3MDQuMjA5LDI3MDkuNDk5LDI3MjcuMzM5LDI3MzcuMzk3LDI3NDgu MTA4LDI3MzcuODY1LDI3MDUuMjE2LDI3MDkuMDE4LDI3MDYuNjEyLDI3MTIu MzkyLDI3MDIuMjg0LDI3MDcuODYsMjY4NS4zMzQsMjcxMS41ODYsMjcwMC4x MjMsMjcxMi43NTkNCmJhc2UsMSwxMDAwLDEwMDAwMCwzNzk3LjAyMiwzODAx LjcwMSwzODQ1Ljk1NSwzODAwLjI3NywzNzk5LjI2OSwzODA0Ljg5OSwzNzk4 LjMzNywzNzk3Ljk5NiwzODAzLjgxMiwzNzk3LjA4NCwzNzk5LjAwNSwzODAz LjE2NSwzNzk1Ljc3OSwzODg2LjM2OCwzODA1LjU2NywzODAxLjEsMzc5Ni44 MDgsMzc5OS4xNjcsMzgwMS4xMzksMzgyNC43NTYsMzc5Ny45MzMsMzgyNC4x ODYsMzc5OS42MTYsMzgwNC40NTgsMzgwNy43MjUNCnRlc3QsMSwxMDAwLDEw MDAwMCwzNzkxLjI1NiwzNzkwLjIyNiwzNzg3LjE0OSwzNzg3LjM4MywzODQy LjQzOSwzNzg3LjUzMSwzNzg5LjQ2NiwzNzg4LjE1OSwzNzkwLjI4MiwzNzc3 LjcwMywzNzg4LjYwNywzNzg4LjYzNCwzNzg5LjI4OSwzNzgzLjQ3OCwzNzg1 LjIwMywzNzk2LjU1OCwzNzg3LjE2NSwzNzg5LjI1MywzNzM5LjA5NSwzODA5 LjA2NywzNzkwLjI1NywzNzg5LjEzNCwzNzg4LjQ1LDM3OTEuMjYyLDM3ODku NDYNCmJhc2UsMiwxMDAwLDEwMDAwMCwyNzcwLjY1MywyNzY2LjE2NSwyNzY2 LjQzMiwyNzcxLjAxOSwyNzY0Ljg0MSwyNzczLjM5NCwyNzY4LjgwOSwyNzcx LjI4NywyNzY2LjI0NiwyNzc3LjE2NiwyNzY5LjYzNCwyNzY1Ljk4NCwyNzY2 LjEyNywyNzU0LjY3MiwyNzY4LjIyOSwyNzcyLjkwMSwyNzY5LjEyMywyNzcz LjE1OSwyNzc0LjkwNiwyNzY0LjU2OSwyNzY2LjQ5NiwyNzY1LjM1LDI3Njcu NjA4LDI3NzAuNDIzLDI3NjguNTUNCnRlc3QsMiwxMDAwLDEwMDAwMCwyNzE2 Ljc3OCwyNzE0LjgwNCwyNzE1LjY1NSwyNzIwLjkyMywyNzE5LjYzNCwyNzMx LjQ5NSwyNzE4LjkzNiwyNzQyLjkwMiwyNjk5Ljk4NCwyNzIzLjk5LDI3MjAu NjQ3LDI3MjQuNDgsMjczOC45NjQsMjcyMC4yNjYsMjczMy40NjgsMjcxNS43 NiwyNzE4LjcxNywyNzE2LjU2MiwyNzI1LjE5OCwyNzE3LjM0LDI4MjUuODUs MjczMi44ODQsMjcyMC45NzgsMjcyMS42NjgsMjcyNi41NzgNCmJhc2UsMSwx MDAwMCwxMDAwMCwzODIyLjcyNCwzODIyLjEzNiwzODMyLjcxOCwzODIzLjQ0 NCwzODIyLjA2NiwzODI0LjkzOCwzODQ1LjAzMywzODIzLjY1MywzODI1LjA5 NywzODIxLjYwNywzODU2LjA3MywzODIxLjU3NSwzODIxLjQwNSwzODI0Ljky MywzODIxLjc3LDM4MjMuMDA4LDM4MjEuOTkzLDM4MzkuMzA2LDM4MjAuODc3 LDM5MjUuMjUzLDM4MTcuNzMxLDM4MjEuODE4LDM4MjEuMTczLDM4MjMuNzE2 LDM4MzAuMTY4DQp0ZXN0LDEsMTAwMDAsMTAwMDAsMzc5OS43NjQsMzc4NS45 ODUsMzc4OC41MzQsMzc4OS4zMDQsMzc4Ni41LDM3ODguMTMxLDM4MjUuNjIz LDM3ODUuMzYyLDM3ODQuMzY2LDM4MDEuMDc4LDM3ODQuOTU2LDM3ODQuOTM3 LDM4MjIuMjE5LDM3ODUuNTk1LDM3ODUuOTUzLDM3ODguNDM4LDM3ODQuODY4 LDM3OTEuMTUyLDM3ODYuMTM4LDM3ODYuMDE4LDM3OTAuNTIsMzc5MC4yOTYs Mzc4Ni41OTIsMzc4NS4xOCwzNzkxLjE0Ng0KYmFzZSwyLDEwMDAwLDEwMDAw LDI3OTIuMjM2LDI3OTIuNTkzLDI3OTMuNzgxLDI3OTQuNzQxLDI3OTQuMjAz LDI4MDUuNjM4LDI3OTUuNzQ0LDI3OTEuNjk5LDI4MTYuNzcxLDI3OTIuNzQ1 LDI3OTEuNDc2LDI3OTcuMTYxLDI3OTAuNjgsMjgwNS45NDgsMjc5MC43ODEs Mjc5MC4zMjEsMjc5MC4yMjUsMjgwNy42OSwyNzkwLjMzMywyNzg4Ljg2Nywy Nzk2LjA5OSwyNzk2LjM1OCwyNzk1LjE0MiwyNzk3LjQ0LDI3OTUuNzc4DQp0 ZXN0LDIsMTAwMDAsMTAwMDAsMjc0Ni40MzIsMjc0Mi4xNjQsMjc0NS4zOTMs Mjc2OC45MzgsMjc3MC4xOTQsMjc0Ny41NzMsMjc0Ny43NDUsMjc0NS4wOTYs Mjc0My40ODMsMjc0NC4xMzUsMjc0My42MTYsMjgxMS44OSwyNzQ5LjM4LDI3 NDUuODY4LDI3NDUuODY4LDI3NDQuOTQ4LDI3NjAuODQ0LDI3NDMuNzU2LDI3 NDYuMTI0LDI3NDUuOTA1LDI3NDYuMTI1LDI3NzQuNzQ5LDI3NDUuODYyLDI3 NDcuMjk3LDI3NTIuMjI0DQpiYXNlLDEsMTAwMDAwLDEwMDAsMzgwMy44MTUs MzgwMS4zNzQsMzgwNS43MjMsMzgzOC44MjUsMzgwNy44NDgsMzgwNC41MDYs MzgwOS4zMSwzODA4Ljk2OCwzODA5LjgwNCwzODAzLjU4NSwzODA0LjEwNCwz ODAzLjc1MiwzODMzLjkwNiwzODAxLjkyMiwzODAxLjMxMSwzODA4LjUyOCwz ODAxLjkwOSwzODA5LjE5OCwzODAwLjk1MSwzODA3LjcwNCwzODAyLjE5NSwz ODA4LjUxNiwzODA2LjM5OSwzNzkyLjc5MiwzODA3LjM3Mw0KdGVzdCwxLDEw MDAwMCwxMDAwLDM3NzIuMjUsMzc3My4yODEsMzc3NS44OTQsMzc3My4yMzMs Mzc3OS40NzQsMzc3Ni4zNzcsMzc3Mi4zNDYsMzc3Ni4wNDUsMzc3NC41Mywz Nzc3LjAyMiwzNzcxLjQ4LDM3NzQuMzY4LDM3NzQuMzYxLDM3NzQuMDYxLDM3 NzYuOTkxLDM3ODQuODU3LDM3OTMuNTUzLDM3NzMuMjI3LDM3NzMuNDgxLDM4 MDYuMTIsMzc4MC4wMiwzNzkxLjQ1OCwzNzc2LjUxMywzNzcxLjg1MywzNzc4 LjAzMw0KYmFzZSwyLDEwMDAwMCwxMDAwLDI3NzQuMjI3LDI3NjUuMzE0LDI3 NzAuMjc3LDI3NjcuMDY5LDI3NjMuMjE3LDI3NjAuODc5LDI3NzAuMzc0LDI3 NjguMDE0LDI3NjUuNzMyLDI3NzMuMzkxLDI3NjUuMjM3LDI3NjQuODg4LDI3 NjYuNzc1LDI3NjguNTU2LDI3NzIuMTQzLDI3NjYuMTQ0LDI3NjUuODQ5LDI3 NTkuNTQ2LDI3NjguODU1LDI3NjYuODQ1LDI3NjYuMTI0LDI3NjkuMDU2LDI3 NjguMTcsMjc3MC41NjUsMjc2Ny4zODUNCnRlc3QsMiwxMDAwMDAsMTAwMCwy NzYyLjUzNCwyNjg4Ljg3NSwyNzI3Ljk0MiwyNzMyLjUxMiwyNzMxLjg2Niwy NzMwLjAwOSwyNzMyLjgxOSwyNzMxLjc4NSwyNzI2LjI4MywyNzMwLjM3MSwy NzI1Ljk3MywyNzM3LjA3OCwyNzMxLjgzLDI3MzAuMTY1LDI3MzQuMDE4LDI3 MjcuNDQxLDI3MzAuMzU2LDI3MjkuMTYyLDI3MjkuNjM4LDI3ODEuMDc5LDI3 MjkuMTk2LDI3MzAuODQsMjcyOC44NjgsMjczMC43MTQsMjczMi4xNA0KYmFz ZSwxLDEwMDAwMDAsMTAwLDM3OTUuOTk1LDM3OTQuNDUzLDM3OTguMzUsMzc5 NS40MDgsMzc5Ny40NDksMzc5My4xMzYsMzc5OS44NTIsMzc5OS4wNzMsMzc5 NS44NCwzNzk0LjA2LDM3OTYuMTc0LDM3OTIuOTk1LDM3OTUuNjU2LDM4MDgu MzkzLDM3OTUuMjYxLDM3OTYuNjkyLDM3OTQuODQ1LDM3OTQuODI3LDM3OTMu NDY5LDM4MzQuMjY0LDM3OTYuMjA5LDM3OTIuNzQxLDM4MTYuNTU5LDM3OTcu NDExLDM3OTguNzEzDQp0ZXN0LDEsMTAwMDAwMCwxMDAsMzczMS4zNDYsMzc3 OS4xMjcsMzc4Ny4wNTgsMzc2My4zMzEsMzc4Mi44NzQsMzc4Ny41MjYsMzc4 My45OTgsMzc5NC41NzksMzc4Ny43NDMsMzc4MC4yNzUsMzc4MC4wMTMsMzc3 OC4yNCwzNzc5Ljg2MywzNzg1LjI2NywzNzgyLjU3NywzNzk1LjY3OCwzODY4 LjY1OSwzNzgyLjc2MSwzNzgxLjQ3OCwzNzgxLjAxLDM3ODEuNDYyLDM3ODAu MjksMzc4MS41NDYsMzc2Ny4xNTMsMzc4My40OTQNCmJhc2UsMiwxMDAwMDAw LDEwMCwyNzYxLjQxNywyNzY0LjY4NCwyNzYxLjcwNiwyNzQ5LjY0MSwyNzU5 LjU4MSwyNzY0LjMxMywyNzYwLjg2NywyNzU0LjYxLDI3NjAuODIzLDI3Njgu MjMxLDI3NTkuMTIzLDI3NTkuOTkxLDI3NTkuMTUxLDI3NTguOTYzLDI3NjUu MDQ1LDI3NjAuOTQ5LDI3NjIuMDkxLDI3NjIuMzU5LDI3NzAuNTEyLDI3NjEu NTE0LDI3NTkuNjE4LDI3NTguNzA2LDI3NjkuMzY4LDI3NjMuMjQ1LDI3NjEu NTIxDQp0ZXN0LDIsMTAwMDAwMCwxMDAsMjcxMy42NzEsMjcxNS4xMTYsMjcy My40MTQsMjcxMy4yMTgsMjcxMy4zMTYsMjcyNi42NSwyNzE0LjY5NiwyNjg4 LjA3NiwyNzg5Ljk0NywyNzEyLjIyMiwyNzEwLjUwNiwyNjkxLjU5MiwyNzEz LjE3LDI3MTIuMzk5LDI3MTQuNzM3LDI3MTMuNjc5LDI3MTMuODYyLDI3MTMu NzY2LDI3MTIuODU0LDI3MjQuMzIsMjcxMy4wOTEsMjcxMy44NjEsMjc4MS40 NzIsMjcxNS4yNDUsMjcxOC45NTMNCmJhc2UsMSwxMDAwMDAwMCwxMCwzODQw Ljc5OSwzODIyLjA0LDM4MjMuMDYxLDM4MjMuNjU4LDM4MjIuMTM4LDQwNjUu MTA2LDM4MzYuNTY1LDM4MjYuOTYsMzgyMS43ODcsMzgxOS45NTMsMzgyMi40 MzcsMzgyMy42MTEsMzgyMy40OTcsNDA1MC42NDEsMzgyMC45OTUsMzgyNy40 NTQsNDA2MS41LDM4MjAuNTU2LDM4MjQuMDQyLDM4MjIuOTY2LDM4MjIuNTk4 LDM4MjguOTA1LDM4MjIuNDYyLDM4MjYuMzExLDM4NTQuMTY4DQp0ZXN0LDEs MTAwMDAwMDAsMTAsMzc5NC41MjgsMzc5NC4zMjgsMzc5NS4zMzMsMzc5OC42 OTYsMzc2OS40ODEsMzc5My4wNTMsMzg3My4xNTIsMzc5OS42MTMsMzc5Ni45 ODIsMzc5OC43MTEsMzc5NS4xNzUsMzc5NS45NDEsNDAzMS4wNDksMzgwOS4w NTMsMzc5My4zNjksMzc5My42MDUsMzc5My40LDM3OTMuMDU4LDM3OTUuNjAy LDM3OTQuOTY5LDM3OTYuNjYxLDM3OTcuNDk5LDM3OTQuNzUzLDM3OTcuMjc4 LDM4MDguMTM3DQpiYXNlLDIsMTAwMDAwMDAsMTAsMjc4OS4xMjEsMjc4OC41 MTYsMjc3Ni43NjQsMjc4Ny43NzYsMjc4OS41MDcsMjc5MC4wNjgsMjc3Ny42 OTMsMjc5Mi4yMSwyNzkwLjQxNCwyODAyLjI3OSwyNzg5LjY2MiwyNzg5Ljg2 LDI3ODUuODgxLDI5NzUuOTk3LDI3ODguODU3LDI5NTkuNTI4LDI3ODQuNzA0 LDI3ODkuNjE4LDI3OTAuNzEzLDI3ODguNDY5LDI3ODguNzYyLDI3OTMuMzU1 LDI3OTcuNDkxLDI3OTEuMTE5LDI4MDQuMDk5DQp0ZXN0LDIsMTAwMDAwMDAs MTAsMjczNi4zOTMsMjc0MC42MTMsMjczOC40MTUsMjczNi43MzksMjc0Ni4w ODMsMjc1MC4yNTksMjczOS44OTgsMjczNi43MTUsMjc1Ni4zMjMsMjc0MC44 NjIsMjczOC4zNjgsMjcxNy4xMTQsMjc1MC4wMjMsMjczOS4yNzcsMjczNi43 NTcsMjczNy45MjgsMjczNC44NDEsMjczNi40MTcsMjc0MC41NDMsMjczOS4y MjgsMjc0MS45MDMsMjc0MC45NzMsMjczOC4wOTksMjczOS42NjgsMjczOS43 Mjc= --000000000000cc97ad060f34f44e--