From d8f9bd4b5791a375573edca7576a6057a9dd9b01 Mon Sep 17 00:00:00 2001
From: Janne Blomqvist <janne.blomqvist@aalto.fi>
Date: Thu, 8 Nov 2012 11:10:22 -0800
Subject: [PATCH] Performance enhancement in computing difftime

running the perf profiler on slurmctld on our production cluster (with select/cons_res) showed that with our configuration & workload highest up in the profile are calls to difftime() and _cr_job_list_sort(), in total accounting for ~37% of the total runtime.

By sacrificing some theoretical portability by replacing the calls to difftime() with a simple inline subtraction that 37% should be substantially reduced.

As I saw identical code also in the linear and serial plugins, I fixed those in the same manner, although I don't know if this performance issue turns up when using those plugins.
---
 src/common/macros.h                           | 10 ++++++++++
 src/plugins/select/cons_res/select_cons_res.c |  2 +-
 src/plugins/select/linear/select_linear.c     |  2 +-
 src/plugins/select/serial/select_serial.c     |  2 +-
 4 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/common/macros.h b/src/common/macros.h
index 7f1bcd1888a..04e0300dcc4 100644
--- a/src/common/macros.h
+++ b/src/common/macros.h
@@ -77,6 +77,16 @@ typedef enum {false, true} bool;
 #  define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
+/*
+ * NOTE: ISO C doesn't guarantee that the following works, but POSIX does,
+ * as well as Windows and all reasonable systems. For maximum portability,
+ * one should do:
+ * SLURM_DIFFTIME(a,b) difftime((a), (b))
+ * but this code can show up high in the profile, so use the faster
+ * (in principle unportable but in practice fine) code below.
+ */
+#define SLURM_DIFFTIME(a,b) ((a) - (b))
+
 /* Avoid going over 32 bits for a constant to avoid warnings on some systems */
 #  define UINT64_SWAP_LE_BE(val)      ((uint64_t) (                           \
         (((uint64_t) (val) &                                                  \
diff --git a/src/plugins/select/cons_res/select_cons_res.c b/src/plugins/select/cons_res/select_cons_res.c
index 74a9dab58c0..afe6ca3559e 100644
--- a/src/plugins/select/cons_res/select_cons_res.c
+++ b/src/plugins/select/cons_res/select_cons_res.c
@@ -453,7 +453,7 @@ static int _cr_job_list_sort(void *x, void *y)
 {
 	struct job_record *job1_ptr = (struct job_record *) x;
 	struct job_record *job2_ptr = (struct job_record *) y;
-	return (int) difftime(job1_ptr->end_time, job2_ptr->end_time);
+	return (int) SLURM_DIFFTIME(job1_ptr->end_time, job2_ptr->end_time);
 }
 
 
diff --git a/src/plugins/select/linear/select_linear.c b/src/plugins/select/linear/select_linear.c
index 7d0a2380cd3..149f0d428ab 100644
--- a/src/plugins/select/linear/select_linear.c
+++ b/src/plugins/select/linear/select_linear.c
@@ -2628,7 +2628,7 @@ static int  _cr_job_list_sort(void *x, void *y)
 {
 	struct job_record *job1_ptr = (struct job_record *) x;
 	struct job_record *job2_ptr = (struct job_record *) y;
-	return (int) difftime(job1_ptr->end_time, job2_ptr->end_time);
+	return (int) SLURM_DIFFTIME(job1_ptr->end_time, job2_ptr->end_time);
 }
 
 /*
diff --git a/src/plugins/select/serial/select_serial.c b/src/plugins/select/serial/select_serial.c
index 09c005410a3..f22ac0fd249 100644
--- a/src/plugins/select/serial/select_serial.c
+++ b/src/plugins/select/serial/select_serial.c
@@ -385,7 +385,7 @@ static int _cr_job_list_sort(void *x, void *y)
 {
 	struct job_record *job1_ptr = (struct job_record *) x;
 	struct job_record *job2_ptr = (struct job_record *) y;
-	return (int) difftime(job1_ptr->end_time, job2_ptr->end_time);
+	return (int) SLURM_DIFFTIME(job1_ptr->end_time, job2_ptr->end_time);
 }
 
 
-- 
GitLab