kernel-janitors.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] md/raid6 algorithms: scale test duration for speedier boots
@ 2021-09-09 13:59 Colin King
  0 siblings, 0 replies; only message in thread
From: Colin King @ 2021-09-09 13:59 UTC (permalink / raw)
  To: Neil Brown; +Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

The original code runs for a set run time based on the duration of
2^RAID6_TIME_JIFFIES_LG2. The default kernel value for
RAID6_TIME_JIFFIES_LG2 is 4, however, emperical testing shows that a
value of 3.5 is the sweet spot for getting consistent benchmarking
results and speeding up the run time of the benchmarking.

To achieve 2^3.5 we use the following:
   2^3.5 = 2^4 / 2^0.5
         = 2^4 / sqrt(2)
         = 2^4 * 0.707106781

Too keep this as integer math that is as accurate as required and avoiding
overflow, this becomes:
         = 2^4 * 181 / 256
         = (2^4 * 181) >> 8

We also need to scale down perf by the same factor, however, to
get a good approximate integer result without an overflow we scale
by 2^4.0 * sqrt(2) =
         = 2 ^ 4 * 1.41421356237
         = 2 ^ 4 * 1448 / 1024
         = (2 ^ 4 * 1448) >> 10

This has been tested on 2 AWS instances, a small t2 and a medium m3
with 30 boot tests each and compared to the same instances booted 30
times on an umodified kernel. In all results, we get the same
algorithms being selected and a 100% consistent result over the 30
boots, showing that this optimised jiffy timing scaling does not break
the original functionality.

On the t2.small we see a saving of ~0.126 seconds and t3.medium a saving of
~0.18 seconds.

Tested on a 4 CPU VM on an 8 thread Xeon server; seeing a saving of ~0.35
seconds (average over 50 boots).

The testing included double checking the algorithm chosen by the optimized
selection and seeing the same as pre-optimised version.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 lib/raid6/algos.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 6d5e5000fdd7..5d5b04632168 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -152,6 +152,10 @@ static inline const struct raid6_calls *raid6_choose_gen(
 
 	for (bestgenperf = 0, bestxorperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) {
 		if (!best || (*algo)->prefer >= best->prefer) {
+			/* 2 ^ (RAID6_TIME_JIFFIES_LG2 - 0.5) */
+			const unsigned long raid6_time_jiffies =
+				((1 << RAID6_TIME_JIFFIES_LG2) * 181) >> 8;
+
 			if ((*algo)->valid && !(*algo)->valid())
 				continue;
 
@@ -167,7 +171,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 			while ((j1 = jiffies) == j0)
 				cpu_relax();
 			while (time_before(jiffies,
-					    j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
+					    j1 + raid6_time_jiffies)) {
 				(*algo)->gen_syndrome(disks, PAGE_SIZE, *dptrs);
 				perf++;
 			}
@@ -178,8 +182,8 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				best = *algo;
 			}
 			pr_info("raid6: %-8s gen() %5ld MB/s\n", (*algo)->name,
-				(perf * HZ * (disks-2)) >>
-				(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
+				(((perf * HZ * (disks-2)) >>
+				 (20 - 16 + RAID6_TIME_JIFFIES_LG2)) * 1448) >> 10);
 
 			if (!(*algo)->xor_syndrome)
 				continue;
@@ -191,7 +195,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 			while ((j1 = jiffies) == j0)
 				cpu_relax();
 			while (time_before(jiffies,
-					    j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
+					    j1 + raid6_time_jiffies)) {
 				(*algo)->xor_syndrome(disks, start, stop,
 						      PAGE_SIZE, *dptrs);
 				perf++;
@@ -202,8 +206,8 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				bestxorperf = perf;
 
 			pr_info("raid6: %-8s xor() %5ld MB/s\n", (*algo)->name,
-				(perf * HZ * (disks-2)) >>
-				(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2 + 1));
+				(((perf * HZ * (disks-2)) >>
+				 (20 - 16 + RAID6_TIME_JIFFIES_LG2 + 1)) * 1448) >> 10);
 		}
 	}
 
@@ -215,8 +219,8 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				(20 - PAGE_SHIFT+RAID6_TIME_JIFFIES_LG2));
 			if (best->xor_syndrome)
 				pr_info("raid6: .... xor() %ld MB/s, rmw enabled\n",
-					(bestxorperf * HZ * (disks-2)) >>
-					(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2 + 1));
+					(((bestxorperf * HZ * (disks-2)) >>
+					 (20 - 16 + RAID6_TIME_JIFFIES_LG2 + 1)) * 1448) >> 10);
 		} else
 			pr_info("raid6: skip pq benchmark and using algorithm %s\n",
 				best->name);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-09-09 14:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-09 13:59 [PATCH] md/raid6 algorithms: scale test duration for speedier boots Colin King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).