Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gQNxq-00020d-W8 for pgsql-hackers@arkaria.postgresql.org; Sat, 24 Nov 2018 02:46:35 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gQNxn-0008DD-Rl for pgsql-hackers@arkaria.postgresql.org; Sat, 24 Nov 2018 02:46:31 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gQNxn-0008D6-K6 for pgsql-hackers@lists.postgresql.org; Sat, 24 Nov 2018 02:46:31 +0000 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gQNxf-0000Da-TW for pgsql-hackers@lists.postgresql.org; Sat, 24 Nov 2018 02:46:30 +0000 Received: by mail-wm1-x342.google.com with SMTP id j207so6217818wmj.1 for ; Fri, 23 Nov 2018 18:46:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=IQeJcw/E3VgeBEFZ44GTqWvgAyPlPpTfx0fZef9nFHo=; b=xKjRnGN+omCx8fnSFqT0IZQWwBXNd5X3bMecASv7MbCBPjwgIH6mKSkla5hTVGqQwO ljGBO32tIgFyFk8Nyq/U4+yxHWfwJb8NTy6XNGOV6jCwMoZM8rzqCk7tl1EcmQx1Lknn brsPhj1fkrJLVj/fWYCghz508Mdqgu86W1w3CSByGfaBi0toIMdNVqkoZ3O3b5b4vgkk 4q2CB14Ea/neLRdjharZttEODuYAQa485I4f4LI/m4N6/6mM7Eg1yjPsToooHe8hIokO fhgHvNKg5SrGO1Cr3Ja2s5JN11wv2pWaPWFJSMpuedIvnyTibSk2/4x+Hm6HJZlVAjt9 H6wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=IQeJcw/E3VgeBEFZ44GTqWvgAyPlPpTfx0fZef9nFHo=; b=WSw4kIiu/bxkEIl6Hpx4Sxrfyx7s2XDv49WCd2IWRN3RXO/K9kApN6omfsd2tSZlp9 nq35DnRaRsYGxECRQ3wNv63aVjW2yHG92W2XD7Q/MeQVh5hAQ+X6PAnbGg4gSHzc3cKz /lKi7GFdkalRPWF6MKbGcjkqa7nmbfFElqSKWmYF8U3MCQ8L/qdJKIfRww2phy7169rC wCDGyDHNpoePcGLiuPOlv/MZ7hlQH0hY8m9L9LLDzDqn0K351bvdziRliqkfk5D3E3Bp smu4qC4gXIbsUFHInDKG1CnFIjNa2FDE+utSWUYDHKpTm5g9MwPyv2ZgW6XzNzbSIP/E DLjQ== X-Gm-Message-State: AGRZ1gKjScmmLwP2v6WvNpyqsKuczR4Wdee8vAcWQjrNw95yP6yDaXAZ HzqbLzmyzoeg/0Nyvg8Pt4LXjD5opGOO63E3QOfCKKsA/D8bWtdOhvLVXlC0hJpeAwveCFFTxa7 ZfqGizIH6XASXcrMz97exG1sMxJgAM3WhsSZR0P9xO4N3KcNS9Lby74+jqGAMzK9d6vqAzV/7Kc xlHnhoGI8WR76XOGM0v0lHeQ== X-Google-Smtp-Source: AJdET5f/lCgYh7k3hwB7LPTp1J/vjjQmyabvZxMdDdn1odQmBhnl51x9f61V9iNSYDnOypfP08JeKg== X-Received: by 2002:a1c:4108:: with SMTP id o8mr15311133wma.91.1543027581123; Fri, 23 Nov 2018 18:46:21 -0800 (PST) Received: from [10.137.2.19] (ip-86-49-251-50.net.upcbroadband.cz. [86.49.251.50]) by smtp.gmail.com with ESMTPSA id x79sm20974193wmd.42.2018.11.23.18.46.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Nov 2018 18:46:20 -0800 (PST) Subject: Re: Tid scan improvements To: Edmund Horner Cc: David Rowley , PostgreSQL Developers References: <0aad6687-037c-5f2f-4bbe-50f68e5c4cf6@2ndquadrant.com> From: Tomas Vondra Message-ID: <8d68f680-1a1c-142d-428d-987eb6d16db0@2ndquadrant.com> Date: Sat, 24 Nov 2018 03:46:17 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 11/24/18 1:56 AM, Edmund Horner wrote: > On Fri, 23 Nov 2018 at 07:03, Tomas Vondra wrote: >> On 11/22/18 8:41 AM, David Rowley wrote: >>> ... >>> 3. I'd rather see EnsureTidRangeSpace() keep doubling the size of the >>> allocation until it reaches the required size. See how >>> MakeSharedInvalidMessagesArray() does it. Doing it this way ensures >>> we always have a power of two sized array which is much nicer if we >>> ever reach the palloc() limit as if the array is sized at the palloc() >>> limit / 2 + 1, then if we try to double it'll fail. Of course, it's >>> unlikely to be a problem here, but... the question would be how to >>> decide on the initial size. >> >> I think it kinda tries to do that in some cases, by doing this: >> >> *numAllocRanges *= 2; >> ... >> tidRanges = (TidRange *) >> repalloc(tidRanges, >> *numAllocRanges * sizeof(TidRange)); >> >> The problem here is that what matters is not numAllocRanges being 2^N, >> but the number of bytes allocated being 2^N. Because that's what ends up >> in AllocSet, which keeps lists of 2^N chunks. >> >> And as TidRange is 12B, so this is guaranteed to waste memory, because >> no matter what the first factor is, the result will never be 2^N. > > For simplicity, I think making it a strict doubling of capacity each > time is fine. That's what we see in numerous other places in the > backend code. > Sure. > What we don't really see is intentionally setting the initial capacity > so that each subsequent capacity is close-to-but-not-exceeding a power > of 2 bytes. You can't really do that optimally if working in terms of > whole numbers of items that aren't each a power of 2 size. This step, > there may be 2/3 of an item spare; next step, we'll have a whole item > spare that we're not going to use. Ah, I missed the detail with setting initial size. > So we could keep track in terms of bytes allocated, and then figure > out how many items we can fit at the current time. > > In my opinion, such complexity is overkill for Tid scans. > > Currently, we try to pick an initial size based on the number of > expressions. We assume each expression will yield one range, and > allow that a saop expression might require us to enlarge the array. > > Again, for simplicity, we should scrap that and pick something like > floor(256/sizeof(TidRange)) = 21 items, with about 1.5% wastage. > Probably. I don't think it'd be a lot of code to do the exact sizing, but you're right 1.5% is close enough. As long as there is a comment explaining the initial sizing, I'm fine with that. If I could suggest one more thing, I'd define a struct combining the array of ranges, numRanges and numAllocRangeslike: typedef struct TidRanges { int numRanges; int numAllocRanges; TidRange ranges[FLEXIBLE_ARRAY_MEMBER]; } TidRanges; and use that instead of the plain array. I find it easier to follow compared to passing the various fields directly (sometimes as a value, sometimes pointer to the value, etc.). regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services