From f1289ade91dfd32bfea4378d3c2ce1e7693c49e4 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Fri, 27 Feb 2026 22:59:46 +0000 Subject: [PATCH 1/2] refactor: use snprintf to clean up WriteStats The deeply-nested conditions on the length of the sizes is due to MesPrint truncating numbers which are too long for positioned fields, rather than loosening the positioning. snprintf doesn't truncate, so is much easier to align. --- sources/sort.c | 460 +++++++++---------------------------------------- 1 file changed, 79 insertions(+), 381 deletions(-) diff --git a/sources/sort.c b/sources/sort.c index 1005e17c..eb2652a4 100644 --- a/sources/sort.c +++ b/sources/sort.c @@ -108,6 +108,16 @@ void HumanString(char* string, float input, const char suffix[HUMANSUFFLEN][4]) } } +WORD DigitsIn(LONG x) { + if ( x < 0 ) x = -x; + WORD dig = 1; + while ( x > 9 ) { + dig++; + x /= 10; + } + return dig; +} + /** * Writes the statistics. * @@ -127,11 +137,12 @@ void HumanString(char* string, float input, const char suffix[HUMANSUFFLEN][4]) void WriteStats(POSITION *plspace, WORD par, WORD checkLogType) { GETIDENTITY - LONG millitime, y = 0x7FFFFFFFL >> 1; + char buf[120]; + LONG millitime; WORD timepart; SORTING *S; - POSITION pp; int use_wtime; + if ( AT.SS == AT.S0 && AC.StatsFlag ) { #ifdef WITHPTHREADS if ( AC.ThreadStats == 0 && identity > 0 ) return; @@ -201,423 +212,110 @@ void WriteStats(POSITION *plspace, WORD par, WORD checkLogType) #elif defined(WITHMPI) if ( use_wtime && PF.me != MASTER ) use_wtime = 0; #endif + char *wpref = use_wtime ? "W" : ""; + char *wspac = use_wtime ? "" : " "; millitime = use_wtime ? TimeWallClock(1) * 10 : TimeCPU(1); timepart = (WORD)(millitime%1000); millitime /= 1000; timepart /= 10; + if ( AC.ShortStats ) { #if defined(WITHPTHREADS) || defined(WITHMPI) #ifdef WITHPTHREADS - if ( identity > 0 ) { + if ( identity > 0 ) { #else - if ( PF.me != MASTER ) { - const int identity = PF.me; -#endif - if ( par == STATSSPLITMERGE || par == STATSPOSTSORT ) { - SETBASEPOSITION(pp,y); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%10p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); -/* - MesPrint("%d: %14s %17s %7l.%2is %8l>%10l%3s%10l:%10p",identity, - EXPRNAME(AR.CurExpr),AC.Commercial,millitime,timepart, - AN.ninterms,S->GenTerms,toterms[par],S->TermsLeft,plspace); -*/ - } - else { - y = 1000000000L; - SETBASEPOSITION(pp,y); - MULPOS(pp,100); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%11p %s %s",identity, + if ( PF.me != MASTER ) { + const int identity = PF.me; +#endif + if ( par == STATSSPLITMERGE || par == STATSPOSTSORT ) { + snprintf(buf, sizeof(buf), + "%d: %7ld.%02us %8ld>%10ld%3s%10ld:%10ld %s %s",identity, millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%12p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%13p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%14p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%15p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%16p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %8l>%10l%3s%10l:%17p %s %s",identity, - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - } } } } } - } + S->TermsLeft,BASEPOSITION(*plspace),EXPRNAME(AR.CurExpr), + AC.Commercial); + MesPrint("%s", buf); } - } - else if ( par == STATSMERGETOFILE ) { - SETBASEPOSITION(pp,y); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%10p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - y = 1000000000L; - SETBASEPOSITION(pp,y); - MULPOS(pp,100); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%11p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%12p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%13p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%14p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%15p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%16p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%d: %7l.%2is %10l:%17p",identity,millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - } } } } } - } + else if ( par == STATSMERGETOFILE ) { + snprintf(buf, sizeof(buf), + "%d: %7ld.%02us %10ld:%10ld",identity,millitime,timepart, + S->TermsLeft,BASEPOSITION(*plspace)); + MesPrint("%s", buf); } - } } else + } + else #endif { - if ( par == STATSSPLITMERGE || par == STATSPOSTSORT ) { - SETBASEPOSITION(pp,y); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%10p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); -/* - MesPrint("%14s %17s %7l.%2is %8l>%10l%3s%10l:%10p", - EXPRNAME(AR.CurExpr),AC.Commercial,millitime,timepart, - AN.ninterms,S->GenTerms,toterms[par],S->TermsLeft,plspace); -*/ - } - else { - y = 1000000000L; - SETBASEPOSITION(pp,y); - MULPOS(pp,100); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%11p %s %s", + if ( par == STATSSPLITMERGE || par == STATSPOSTSORT ) { + snprintf(buf, sizeof(buf), + "%7ld.%02us %8ld>%10ld%3s%10ld:%10ld %s %s", millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%12p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%13p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%14p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%15p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%16p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %8l>%10l%3s%10l:%17p %s %s", - millitime,timepart,AN.ninterms,S->GenTerms,toterms[par], - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - } } } } } - } + S->TermsLeft,BASEPOSITION(*plspace),EXPRNAME(AR.CurExpr), + AC.Commercial); + MesPrint("%s", buf); } - } - else if ( par == STATSMERGETOFILE ) { - SETBASEPOSITION(pp,y); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%10p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - y = 1000000000L; - SETBASEPOSITION(pp,y); - MULPOS(pp,100); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%11p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%12p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%13p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%14p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%15p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%16p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%7l.%2is %10l:%17p",millitime,timepart, - S->TermsLeft,plspace,EXPRNAME(AR.CurExpr),AC.Commercial); - } - } } } } } - } + else if ( par == STATSMERGETOFILE ) { + snprintf(buf, sizeof(buf), + "%7ld.%02us %10ld:%10ld",millitime,timepart, + S->TermsLeft,BASEPOSITION(*plspace)); + MesPrint("%s", buf); } } - } } - else { - if ( par == STATSMERGETOFILE ) { - if ( use_wtime ) { - MesPrint("WTime = %7l.%2i sec",millitime,timepart); - } - else { - MesPrint("Time = %7l.%2i sec",millitime,timepart); - } } else { -#if ( BITSINLONG > 32 ) - if ( S->GenTerms >= 10000000000L ) { - if ( use_wtime ) { - MesPrint("WTime = %7l.%2i sec Generated terms = %16l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } - else { - MesPrint("Time = %7l.%2i sec Generated terms = %16l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } - } - else { - if ( use_wtime ) { - MesPrint("WTime = %7l.%2i sec Generated terms = %10l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } - else { - MesPrint("Time = %7l.%2i sec Generated terms = %10l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } - } -#else - if ( use_wtime ) { - MesPrint("WTime = %7l.%2i sec Generated terms = %10l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } - else { - MesPrint("Time = %7l.%2i sec Generated terms = %10l%s", - millitime,timepart,S->GenTerms,humanGenTermsText); - } -#endif - } -#if ( BITSINLONG > 32 ) - if ( par == STATSSPLITMERGE ) - if ( S->TermsLeft >= 10000000000L ) { - MesPrint("%16s%8l Terms %s = %16l%s",EXPRNAME(AR.CurExpr), - AN.ninterms,FG.swmes[par],S->TermsLeft,humanTermsLeftText); + if ( par == STATSMERGETOFILE ) { + snprintf(buf, sizeof(buf), + "%sTime = %7ld.%02u sec",wpref,millitime,timepart); + MesPrint("%s", buf); } else { - MesPrint("%16s%8l Terms %s = %10l%s",EXPRNAME(AR.CurExpr), - AN.ninterms,FG.swmes[par],S->TermsLeft,humanTermsLeftText); + snprintf(buf, sizeof(buf), + "%sTime = %7ld.%02u sec %sGenerated terms = %10ld%s", + wpref,millitime,timepart,wspac,S->GenTerms,humanGenTermsText); + MesPrint("%s", buf); } - else { - if ( S->TermsLeft >= 10000000000L ) { -#ifdef WITHPTHREADS - if ( identity > 0 && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in thread = %16l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); - } - else -#elif defined(WITHMPI) - if ( PF.me != MASTER && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in process= %16l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); - } - else -#endif - { - MesPrint("%16s Terms %s = %16l%s", - EXPRNAME(AR.CurExpr),FG.swmes[par],S->TermsLeft,humanTermsLeftText); - } + + if ( par == STATSSPLITMERGE ) { + snprintf(buf, sizeof(buf), + "%16s%8ld Terms %s = %10ld%s", + EXPRNAME(AR.CurExpr),AN.ninterms,FG.swmes[par],S->TermsLeft, + humanTermsLeftText); + MesPrint("%s", buf); } else { #ifdef WITHPTHREADS if ( identity > 0 && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in thread = %10l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); + snprintf(buf, sizeof(buf), + "%16s Terms in thread = %10ld%s", + EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); + MesPrint("%s", buf); } else #elif defined(WITHMPI) if ( PF.me != MASTER && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in process= %10l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); + snprintf(buf, sizeof(buf), + "%16s Terms in process= %10ld%s", + EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); + MesPrint("%s", buf); } else #endif { - MesPrint("%16s Terms %s = %10l%s", - EXPRNAME(AR.CurExpr),FG.swmes[par],S->TermsLeft,humanTermsLeftText); + snprintf(buf, sizeof(buf), + "%16s Terms %s = %10ld%s", + EXPRNAME(AR.CurExpr),FG.swmes[par],S->TermsLeft, + humanTermsLeftText); + MesPrint("%s", buf); } } + + const WORD dig = DigitsIn(BASEPOSITION(*plspace)); + snprintf(buf, sizeof(buf), "%24s Bytes used%*s=%11ld%s", + AC.Commercial,MiN(6,17-dig),"",BASEPOSITION(*plspace), + humanBytesText); + MesPrint("%s", buf); } -#else - if ( par == STATSSPLITMERGE ) - MesPrint("%16s%8l Terms %s = %10l%s",EXPRNAME(AR.CurExpr), - AN.ninterms,FG.swmes[par],S->TermsLeft,humanTermsLeftText); - else { -#ifdef WITHPTHREADS - if ( identity > 0 && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in thread = %10l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); - } - else -#elif defined(WITHMPI) - if ( PF.me != MASTER && par == STATSPOSTSORT ) { - MesPrint("%16s Terms in process= %10l%s", - EXPRNAME(AR.CurExpr),S->TermsLeft,humanTermsLeftText); - } - else -#endif - { - MesPrint("%16s Terms %s = %10l%s", - EXPRNAME(AR.CurExpr),FG.swmes[par],S->TermsLeft,humanTermsLeftText); - } } -#endif - SETBASEPOSITION(pp,y); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used = %10p%s",AC.Commercial,plspace,humanBytesText); - } - else { - y = 1000000000L; - SETBASEPOSITION(pp,y); - MULPOS(pp,100); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%11p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%12p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%13p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%14p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%15p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used =%16p%s",AC.Commercial,plspace,humanBytesText); - } - else { - MULPOS(pp,10); - if ( ISLESSPOS(*plspace,pp) ) { - MesPrint("%24s Bytes used=%17p%s",AC.Commercial,plspace,humanBytesText); - } - } } } } } - } - } } + #ifdef WITHSTATS MesPrint("Total number of writes: %l, reads: %l, seeks, %l" ,numwrites,numreads,numseeks); From 69dad232ebae1d02c1dc544da26e224655ca803c Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Fri, 27 Feb 2026 23:10:47 +0000 Subject: [PATCH 2/2] feat: add "On SortVerbose;" for extra sort info Add information to the final sort summaries (per thread and master) including the number of comparisons made, and the number of times the small and large buffers were sorted due to their capacities. --- sources/compcomm.c | 1 + sources/sort.c | 70 +++++++++++++++++++++++----------------------- sources/structs.h | 6 ++++ sources/threads.c | 27 ++++++++++++++++++ 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/sources/compcomm.c b/sources/compcomm.c index da4b8a34..07c7746d 100644 --- a/sources/compcomm.c +++ b/sources/compcomm.c @@ -143,6 +143,7 @@ static KEYWORDV onoffoptions[] = { ,{"humanstats", &(AC.HumanStatsFlag), 1, 0} ,{"humanstatistics", &(AC.HumanStatsFlag), 1, 0} ,{"grccverbose", &(AC.GrccVerbose), 1, 0} + ,{"sortverbose", &(AC.SortVerbose), 1, 0} }; static WORD one = 1; diff --git a/sources/sort.c b/sources/sort.c index eb2652a4..2045dce5 100644 --- a/sources/sort.c +++ b/sources/sort.c @@ -72,14 +72,6 @@ extern LONG nummallocs; extern LONG numfrees; #endif -//#define COUNTCOMPARES -#ifdef COUNTCOMPARES - // This needs to be large enough for the number of threads. - // It is hardcoded here, but 1024 should be enough. - // Enabling this has a performance impact. - LONG numcompares[1024]; -#endif - /* #] Includes : #[ SortUtilities : @@ -164,10 +156,12 @@ void WriteStats(POSITION *plspace, WORD par, WORD checkLogType) char humanGenTermsText[HUMANSTRLEN] = ""; char humanTermsLeftText[HUMANSTRLEN] = ""; char humanBytesText[HUMANSTRLEN] = ""; + char humanComparisonsText[HUMANSTRLEN] = ""; if ( AC.HumanStatsFlag ) { HumanString(humanGenTermsText, (float)(S->GenTerms), humanTermsSuffix); HumanString(humanTermsLeftText, (float)(S->TermsLeft), humanTermsSuffix); HumanString(humanBytesText, (float)(BASEPOSITION(*plspace)), humanBytesSuffix); + HumanString(humanComparisonsText, (float)(S->verbComparisons), humanTermsSuffix); } MLOCK(ErrorMessageLock); @@ -314,6 +308,19 @@ void WriteStats(POSITION *plspace, WORD par, WORD checkLogType) humanBytesText); MesPrint("%s", buf); } + + if ( par == STATSPOSTSORT ) { + if ( AC.SortVerbose ) { + snprintf(buf, sizeof(buf), "%24s Comparisons =%11ld%s", + "",S->verbComparisons,humanComparisonsText); + MesPrint("%s", buf); + snprintf(buf, sizeof(buf), "%24s Small Buffer =%5ld,%5ld", + "",S->verbSBsortTerms,S->verbSBsortCap); + MesPrint("%s", buf); + snprintf(buf, sizeof(buf), "%24s Large Buffer =%5ld,%5ld", + "",S->verbLBsortPatches,S->verbLBsortCap); + MesPrint("%s", buf); + } } #ifdef WITHSTATS @@ -363,14 +370,6 @@ int NewSort(PHEAD0) } if ( AR.sLevel == 0 ) { -#ifdef COUNTCOMPARES -#ifdef WITHPTHREADS - numcompares[AT.identity] = 0; -#else - numcompares[0] = 0; -#endif -#endif - AN.FunSorts[0] = AT.S0; if ( AR.PolyFun == 0 ) { AT.S0->PolyFlag = 0; } else if ( AR.PolyFunType == 1 ) { AT.S0->PolyFlag = 1; } @@ -409,6 +408,12 @@ int NewSort(PHEAD0) PUTZERO(AN.OldPosOut); */ + // Zero the SortVerbose counters: + S->verbComparisons = 0; + S->verbSBsortTerms = 0; + S->verbSBsortCap = 0; + S->verbLBsortPatches = 0; + S->verbLBsortCap = 0; return(0); } @@ -622,6 +627,10 @@ LONG EndSort(PHEAD WORD *buffer, int par) /* The large buffer is too full. Merge and write it */ + // Update SortVerbose counters + if ( S->lPatch >= S->MaxPatches ) S->verbLBsortPatches++; + else S->verbLBsortCap++; + #ifdef GZIPDEBUG MLOCK(ErrorMessageLock); MesPrint("%w EndSort: lPatch = %d, MaxPatches = %d,lFill = %x, sSpace = %ld, MaxTer = %d, lTop = %x" @@ -978,18 +987,6 @@ LONG EndSort(PHEAD WORD *buffer, int par) } } -#ifdef COUNTCOMPARES - if ( AR.sLevel < 0 ) { -#ifdef WITHPTHREADS - MLOCK(ErrorMessageLock); - MesPrint(">>>number of calls to Compare: %l (tid %d)", numcompares[AT.identity], AT.identity); - MUNLOCK(ErrorMessageLock); -#else - MesPrint(">>>number of calls to Compare: %l", numcompares[0]); -#endif - } -#endif - return(retval); WorkSpaceError: MLOCK(ErrorMessageLock); @@ -2345,15 +2342,10 @@ WORD Compare1(PHEAD WORD *term1, WORD *term2, WORD level) WORD prevorder; WORD count = -1, localPoly, polyhit = -1; -#ifdef COUNTCOMPARES if ( AR.sLevel == 0 ) { -#ifdef WITHPTHREADS - numcompares[AT.identity]++; -#else - numcompares[0]++; -#endif + // Update SortVerbose counter at ground level only + S->verbComparisons++; } -#endif if ( S->PolyFlag ) { /* @@ -4267,6 +4259,10 @@ int StoreTerm(PHEAD WORD *term) /* The small buffer is full. It has to be sorted and written. */ + // Update SortVerbose counters + if ( S->sTerms >= S->TermsInSmall ) S->verbSBsortTerms++; + else S->verbSBsortCap++; + tover = over = S->sTerms; ss = S->sPointer; ss[over] = 0; @@ -4299,6 +4295,10 @@ int StoreTerm(PHEAD WORD *term) /* The large buffer is too full. Merge and write it */ + // Update SortVerbose counters + if ( S->lPatch >= S->MaxPatches ) S->verbLBsortPatches++; + else S->verbLBsortCap++; + if ( MergePatches(1) ) goto StoreCall; /* pp = S->SizeInFile[1]; diff --git a/sources/structs.h b/sources/structs.h index 651a6ddf..743eb440 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -1156,6 +1156,11 @@ typedef struct sOrT { LONG SpaceLeft; /* Space needed for still existing terms */ LONG putinsize; /* Size of buffer in putin */ LONG ninterms; /* Which input term ? */ + LONG verbComparisons; /* Counters for "On SortVerbose;" statistics */ + LONG verbSBsortTerms; + LONG verbSBsortCap; + LONG verbLBsortPatches; + LONG verbLBsortCap; int MaxPatches; /* Maximum number of patches in large buffer */ int MaxFpatches; /* Maximum number of patches in one filesort */ int type; /* Main, function or sub(routine) */ @@ -1826,6 +1831,7 @@ struct C_const { int FlintPolyFlag; /* Use Flint for polynomial arithmetic */ int HumanStatsFlag; /* Print human-readable stats in the stats print? */ int GrccVerbose; /* Enable extra print statements in grcc? */ + int SortVerbose; /* Enable extra sort stats information? */ int doloopstacksize; int dolooplevel; int CheckpointFlag; /**< Tells preprocessor whether checkpoint code must executed. diff --git a/sources/threads.c b/sources/threads.c index 9176e4c6..2357b268 100644 --- a/sources/threads.c +++ b/sources/threads.c @@ -1987,6 +1987,8 @@ void *RunSortBot(void *dummy) AT.SB.FillBlock = 1; AT.SB.MasterFill[1] = AT.SB.MasterStart[1]; SETBASEPOSITION(AN.theposition,0); + // Reset the sortbot comparison count + AT.SS->verbComparisons = 0; break; /* #] INISORTBOT : @@ -4052,10 +4054,21 @@ int MasterMerge(void) fin->handle = -1; position = S->SizeInFile[0]; MULPOS(position,sizeof(WORD)); + + // Collect global sort statistics information from the threads. + // The total GenTerms is the sum of the thread GenTerms. + // The total small/large buffer sort info is the sum of the thread info. + // The total comparison count is the sum of the thread counts. S->GenTerms = 0; for ( j = 1; j <= numberofworkers; j++ ) { S->GenTerms += AB[j]->T.SS->GenTerms; + S->verbComparisons += AB[j]->T.SS->verbComparisons; + S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms; + S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap; + S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches; + S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap; } + WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE); Expressions[AR0.CurExpr].counter = S->TermsLeft; Expressions[AR0.CurExpr].size = position; @@ -4193,10 +4206,24 @@ int SortBotMasterMerge(void) } position = S->SizeInFile[0]; MULPOS(position,sizeof(WORD)); + + // Collect global sort statistics information from the threads. + // The total GenTerms is the sum of the thread GenTerms. + // The total small/large buffer sort info is the sum of the thread info. + // The total comparison count is the sum of the thread and sortbot counts. S->GenTerms = 0; for ( j = 1; j <= numberofworkers; j++ ) { S->GenTerms += AB[j]->T.SS->GenTerms; + S->verbComparisons += AB[j]->T.SS->verbComparisons; + S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms; + S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap; + S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches; + S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap; } + for ( j = numberofworkers+1; j <= numberofworkers+numberofsortbots; j++ ) { + S->verbComparisons += AB[j]->T.SS->verbComparisons; + } + S->TermsLeft = numberofterms; WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE); Expressions[AR.CurExpr].counter = S->TermsLeft;