You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(2) |
2
(9) |
|
3
(1) |
4
|
5
(1) |
6
(3) |
7
(1) |
8
|
9
(3) |
|
10
|
11
(4) |
12
|
13
(24) |
14
(14) |
15
(22) |
16
|
|
17
|
18
(4) |
19
(4) |
20
(3) |
21
|
22
|
23
|
|
24
|
25
(2) |
26
|
27
(2) |
28
|
29
|
30
|
|
31
|
|
|
|
|
|
|
|
From: Nicholas N. <nj...@so...> - 2020-05-07 22:41:05
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=968bddcd4b4a6565fcd120523c7b33bfd77b5c65 commit 968bddcd4b4a6565fcd120523c7b33bfd77b5c65 Author: Nicholas Nethercote <nne...@mo...> Date: Thu May 7 11:50:55 2020 +1000 Fix reads and writes counts in DHAT. If you do `malloc(100)` followed by `realloc(200)`, DHAT now adds 100 bytes to the read and write counts for the implicit `memcpy`. This gives more reasonable results. I have long been surprised by low writes-per-byte values of around 0.35 for vectors that are grown by doubling. Counting the implicit `memcpy` increases those numbers to well above 0.5, which is what you'd expect. The commit also adds a section to the DHAT docs about `realloc`, because there is some non-obvious behaviour, some of which confused me just a couple of days ago. Diff: --- NEWS | 4 ++++ dhat/dh_main.c | 19 ++++++++++++++---- dhat/docs/dh-manual.xml | 47 +++++++++++++++++++++++++++++++++++++++++++++ dhat/tests/basic.c | 8 +++++--- dhat/tests/basic.stderr.exp | 6 +++--- 5 files changed, 74 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index 5179c7f894..53908689a6 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,10 @@ support for X86/macOS 10.13, AMD64/macOS 10.13 and nanoMIPS/Linux. * DHAT: + - The implicit memcpy done by each call to realloc now counts towards the + read and write counts of resized heap blocks, making those counts higher + and more accurate. + * Cachegrind: - cg_annotate's --auto and --show-percs options now default to 'yes', because diff --git a/dhat/dh_main.c b/dhat/dh_main.c index e13d8b8e3b..565b0ae2d8 100644 --- a/dhat/dh_main.c +++ b/dhat/dh_main.c @@ -62,7 +62,7 @@ static ULong g_max_blocks = 0; static ULong g_max_bytes = 0; static ULong g_max_instrs = 0; -// Values for the entire run. Computed at the end. +// Values for the entire run. Updated each time a block is retired. static ULong g_reads_bytes = 0; static ULong g_writes_bytes = 0; @@ -616,6 +616,13 @@ void* renew_block ( ThreadId tid, void* p_old, SizeT new_req_szB ) // New size is smaller or same; block not moved. resize_Block(bk->ap, bk->req_szB, new_req_szB); bk->req_szB = new_req_szB; + + // Update reads/writes for the implicit copy. Even though we didn't + // actually do a copy, we act like we did, to match up with the fact + // that we treat this as an additional allocation. + bk->reads_bytes += new_req_szB; + bk->writes_bytes += new_req_szB; + return p_old; } else { @@ -636,15 +643,19 @@ void* renew_block ( ThreadId tid, void* p_old, SizeT new_req_szB ) // interval tree at the new place. Do this by removing // and re-adding it. delete_Block_starting_at( (Addr)p_old ); - // now 'bk' is no longer in the tree, but the Block itself - // is still alive + // Now 'bk' is no longer in the tree, but the Block itself + // is still alive. + + // Update reads/writes for the copy. + bk->reads_bytes += bk->req_szB; + bk->writes_bytes += bk->req_szB; // Update the metadata. resize_Block(bk->ap, bk->req_szB, new_req_szB); bk->payload = (Addr)p_new; bk->req_szB = new_req_szB; - // and re-add + // And re-add it to the interval tree. Bool present = VG_(addToFM)( interval_tree, (UWord)bk, (UWord)0/*no val*/); tl_assert(!present); diff --git a/dhat/docs/dh-manual.xml b/dhat/docs/dh-manual.xml index da71720c33..bd318f563e 100644 --- a/dhat/docs/dh-manual.xml +++ b/dhat/docs/dh-manual.xml @@ -620,6 +620,53 @@ optimization.</para> </sect1> +<sect1 id="dh-manual.options" xreflabel="Treatment of realloc"> +<title>Treatment of <computeroutput>realloc</computeroutput></title> + +<para><computeroutput>realloc</computeroutput> is a tricky function and there +are several different ways that DHAT could handle it.</para> + +<para>Imagine a <computeroutput>malloc(100)</computeroutput> call followed by +a <computeroutput>realloc(200)</computeroutput> call. This combination is +considered to add two to the total block count, and 300 bytes to the total +bytes count. (An alternative would be to only add one to the total block +count, and 200 bytes to the total bytes count, as if a single +<computeroutput>malloc(200)</computeroutput> call had occurred. While this +would be defensible from a semantic point of view, it is silly from an +operational point of view, because making two calls to allocator functions is +more expensive than one call, and DHAT is a profiler that aims to help with +runtime costs.)</para> + +<para>Furthermore, the implicit copying of the 100 bytes is added to the reads +and writes counts. Without this, the read and write counts would be +under-measured and misleading.</para> + +<para>However, DHAT only increases the current heap size by 100 bytes for this +combination, and does not change the current block count. (As opposed to +increasing the current heap size by 200 bytes and then decreasing it by 100 +bytes.) As a result, it can only increase the global heap peak (if indeed, +this results in a new peak) by 100 bytes.</para> + +<para>Finally, the allocation point assigned to the block allocated by the +<computeroutput>malloc(100)</computeroutput> call is retained once the block +is reallocated. Which means that all 300 bytes are attributed to that +allocation point, and no separate allocation point is created for the +<computeroutput>realloc(200)</computeroutput> call. This may be surprising, +but it has one large benefit.</para> + +<para>Imagine some code that starts with an empty buffer, and then gradually +adds data to that buffer from numerous different points in the code, +reallocating the buffer each time it gets full. (E.g. code generation in a +compiler might work this way.) With the described approach, the first heap +block and all subsequent heap blocks are attributed to the same allocation +point. While this is something of a lie -- the first allocation point isn't +actually responsible for the other allocations -- it is arguably better than +having the allocation points spread around, in a distribution +that unpredictably depends on whenever the reallocation points were +triggered.</para> + +</sect1> + <sect1 id="dh-manual.options" xreflabel="DHAT Command-line Options"> <title>DHAT Command-line Options</title> diff --git a/dhat/tests/basic.c b/dhat/tests/basic.c index 3ac6617a40..abb7ef4364 100644 --- a/dhat/tests/basic.c +++ b/dhat/tests/basic.c @@ -15,12 +15,14 @@ int main(void) c[i + 1000] = c[i]; // read and write 1000 bytes } - char* r = realloc(m, 3000); + char* r = realloc(m, 3000); // read and write 1000 bytes (memcpy) for (int i = 0; i < 500; i++) { r[i + 2000] = 99; // write 500 bytes } - // totals: 1008 read, 1516 write - free(c); + c = realloc(c, 1000); // read and write 1000 bytes (memcpy) + + free(c); + // totals: 3008 read, 3516 write return 0; } diff --git a/dhat/tests/basic.stderr.exp b/dhat/tests/basic.stderr.exp index cc714443dd..c846d1e33a 100644 --- a/dhat/tests/basic.stderr.exp +++ b/dhat/tests/basic.stderr.exp @@ -1,5 +1,5 @@ -Total: 6,000 bytes in 3 blocks +Total: 7,000 bytes in 4 blocks At t-gmax: 5,000 bytes in 2 blocks At t-end: 3,000 bytes in 1 blocks -Reads: 1,008 bytes -Writes: 1,516 bytes +Reads: 3,008 bytes +Writes: 3,516 bytes |