All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Marques <pmarques@grupopie.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Andi Kleen <ak@muc.de>, linux-kernel@vger.kernel.org
Subject: Re: [patch] Latency Tracer, voluntary-preempt-2.6.8-rc4-O6
Date: Sat, 14 Aug 2004 05:50:50 +0100	[thread overview]
Message-ID: <411D9A2A.1000202@grupopie.com> (raw)
In-Reply-To: <20040813135109.GA20638@elte.hu>

[-- Attachment #1: Type: text/plain, Size: 2156 bytes --]

Ingo Molnar wrote:
>...
> 
>>With binary search you would need to backward search to find the stem
>>for the stem compression. It's probably doable, but would be a bit
>>ugly I guess.
> 
> 
> yeah. Maybe someone will find the time to improve the algorithm. But
> it's not a highprio thing.

Well, I found some time and decided to give it a go :)

I first built a small test program that could provide the same symbol 
data to the lookup function, so that I could test using a user space app.

This way I could benchmark both the original algorithm and any 
improvement I could make, and do it confortably from user space.

The original algorithm took, on average, 1340us per lookup on my P4 
2.8GHz. The compile settings for the test are not the same on the 
kernel, so this can be only compared against other results from the same 
setup.

With the attached patch it takes 14us per lookup. This is almost a 100x 
improvement.

The largest portion of the time it took to do a lookup, was the 
decompression of the symbol names. It seemed a waste of time to keep 
strcpy'ing over the result lots of names that would probably not 
contribute to the final name.

With the strcpy's out, the speed-up was around 5x, but even then, 
looking sequentially for the symbol name was still slow.

The final algorithm pre-calculates markers on the compressed symbols so 
that the search time is almost divided by the number of markers.

There are still a few issues with this approach. The biggest issue is 
that this is clearly a speed/space trade-off, and maybe we don't want to 
waste the space on a code path that is not supposed to be "hot". If this 
is the case, I can make a smaller patch, that fixes just the name 
"decompression" strcpy's.

As always, any comments will be greatly appreciated.


Just one side note: gcc gives a warning about 2 variables that might be 
used before initialization. I know they are not, and it didn't seem a 
good idea to put extra code just to shut up gcc. What is the standard 
way to convince gcc that those vars are ok?

-- 
Paulo Marques - www.grupopie.com
"In a world without walls and fences who needs windows and gates?"

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 4396 bytes --]

--- kernel/kallsyms.c.old	2004-08-14 00:28:58.000000000 +0100
+++ kernel/kallsyms.c	2004-08-14 05:10:09.873194752 +0100
@@ -22,6 +22,13 @@ extern char kallsyms_names[] __attribute
 /* Defined by the linker script. */
 extern char _stext[], _etext[], _sinittext[], _einittext[];
 
+/* auxiliary markers to speed up symbol lookup */
+#define KALLSYMS_STEM_MARKS	8
+
+static int kallsyms_stem_mark_idx[KALLSYMS_STEM_MARKS];
+static char *kallsyms_stem_mark[KALLSYMS_STEM_MARKS];
+
+
 static inline int is_kernel_inittext(unsigned long addr)
 {
 	if (addr >= (unsigned long)_sinittext
@@ -56,13 +63,42 @@ unsigned long kallsyms_lookup_name(const
 	return module_kallsyms_lookup_name(name);
 }
 
+/* build markers into the compressed symbol table, so that lookups can be faster */
+static void build_stem_marks(void)
+{
+	char *name = kallsyms_names;
+	int i, mark_cnt;
+
+	unsigned prefix;
+
+	mark_cnt = 0;
+	for (i = 0 ; i < kallsyms_num_syms; i++) { 
+		prefix=*name;
+		if (prefix == 0) {
+			/* if this is the first 0-prefix stem in the desired interval */
+			if(i > (mark_cnt + 1) * (kallsyms_num_syms / (KALLSYMS_STEM_MARKS + 1)) && 
+			   kallsyms_stem_mark_idx[mark_cnt]==0) {
+				kallsyms_stem_mark[mark_cnt] = name;
+				kallsyms_stem_mark_idx[mark_cnt] = i;
+				mark_cnt++;
+				if(mark_cnt >= KALLSYMS_STEM_MARKS) break;
+			}
+		}
+		do {
+			name++;
+		} while(*name);
+		name ++;
+	}
+}
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
 			    unsigned long *symbolsize,
 			    unsigned long *offset,
 			    char **modname, char *namebuf)
 {
-	unsigned long i, best = 0;
+	unsigned long i, last_0idx;
+	unsigned long mark, low, high, mid;
+	char *last_0prefix;
 
 	/* This kernel should never had been booted. */
 	BUG_ON(!kallsyms_addresses);
@@ -72,39 +108,67 @@ const char *kallsyms_lookup(unsigned lon
 
 	if (is_kernel_text(addr) || is_kernel_inittext(addr)) {
 		unsigned long symbol_end;
-		char *name = kallsyms_names;
+		char *name;
 
-		/* They're sorted, we could be clever here, but who cares? */
-		for (i = 0; i < kallsyms_num_syms; i++) {
-			if (kallsyms_addresses[i] > kallsyms_addresses[best] &&
-			    kallsyms_addresses[i] <= addr)
-				best = i;
+		/* do a binary search on the sorted kallsyms_addresses array */
+		low = 0;
+		high = kallsyms_num_syms;
+		while( high-low > 1 ) { 
+			mid = (low + high) / 2;
+			if( kallsyms_addresses[mid] <= addr ) low = mid;
+			else high = mid;
 		}
 
 		/* Grab name */
-		for (i = 0; i <= best; i++) { 
-			unsigned prefix = *name++;
-			strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix);
-			name += strlen(name) + 1;
-		}
+		i = 0;
+		name = kallsyms_names;
 
-		/* At worst, symbol ends at end of section. */
-		if (is_kernel_inittext(addr))
-			symbol_end = (unsigned long)_einittext;
-		else
-			symbol_end = (unsigned long)_etext;
+		if(kallsyms_stem_mark_idx[0]==0)
+			build_stem_marks();
+
+		for(mark = 0; mark < KALLSYMS_STEM_MARKS; mark++) {
+			if( low >= kallsyms_stem_mark_idx[mark] ) {
+				i = kallsyms_stem_mark_idx[mark];
+				name = kallsyms_stem_mark[mark];
+			}
+			else break;
+		}
 
-		/* Search for next non-aliased symbol */
-		for (i = best+1; i < kallsyms_num_syms; i++) {
-			if (kallsyms_addresses[i] > kallsyms_addresses[best]) {
-				symbol_end = kallsyms_addresses[i];
-				break;
+		/* find the last stem before the actual symbol that as 0 prefix */
+		unsigned prefix;
+		for (; i <= low; i++) { 
+			prefix=*name;
+			if (prefix == 0) {
+				last_0prefix = name;
+				last_0idx = i;
 			}
+			do {
+				name++;
+			} while(*name);
+			name ++;
 		}
 
-		*symbolsize = symbol_end - kallsyms_addresses[best];
+		/* build the name from there */
+		name = last_0prefix;
+		for (i = last_0idx; i <= low; i++) { 
+			prefix = *name++;
+			strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix);
+			name += strlen(name) + 1;
+		}
+
+		if(low == kallsyms_num_syms - 1) {
+			/* At worst, symbol ends at end of section. */
+			if (is_kernel_inittext(addr))
+				symbol_end = (unsigned long)_einittext;
+			else
+				symbol_end = (unsigned long)_etext;
+		}
+		else
+			symbol_end = kallsyms_addresses[low + 1];
+		
+		*symbolsize = symbol_end - kallsyms_addresses[low];
 		*modname = NULL;
-		*offset = addr - kallsyms_addresses[best];
+		*offset = addr - kallsyms_addresses[low];
 		return namebuf;
 	}
 

  reply	other threads:[~2004-08-14  4:51 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <2m9bF-kH-13@gated-at.bofh.it>
     [not found] ` <2m9EG-Js-5@gated-at.bofh.it>
     [not found]   ` <2md5B-36u-11@gated-at.bofh.it>
     [not found]     ` <2mkTt-BZ-11@gated-at.bofh.it>
     [not found]       ` <2nrJd-7Dx-19@gated-at.bofh.it>
     [not found]         ` <2ouFe-2vz-63@gated-at.bofh.it>
     [not found]           ` <2rfT9-5wi-17@gated-at.bofh.it>
     [not found]             ` <2rF1c-6Iy-7@gated-at.bofh.it>
     [not found]               ` <2sxEs-46P-1@gated-at.bofh.it>
     [not found]                 ` <2sCkH-7i5-15@gated-at.bofh.it>
     [not found]                   ` <2sHu9-2EW-31@gated-at.bofh.it>
2004-08-13 12:08                     ` [patch] Latency Tracer, voluntary-preempt-2.6.8-rc4-O6 Andi Kleen
2004-08-13 12:15                       ` Ingo Molnar
2004-08-13 12:16                         ` Ingo Molnar
2004-08-13 12:18                         ` Andi Kleen
2004-08-13 13:51                           ` Ingo Molnar
2004-08-14  4:50                             ` Paulo Marques [this message]
2004-08-14  5:01                               ` Lee Revell
2004-08-14 13:35                                 ` Paulo Marques
2004-08-14 16:49                                   ` Lee Revell
2004-08-14  7:15                               ` Ingo Molnar
2004-08-14 13:32                                 ` Paulo Marques
2004-08-14 12:17                               ` Keith Owens
2004-08-15  0:21                                 ` Paulo Marques
2004-08-17 12:14                                 ` Paulo Marques
2004-08-17 13:05                                   ` Keith Owens
2004-08-17 14:02                                     ` Paulo Marques
2004-08-17 16:23                                       ` Sam Ravnborg
2004-08-17 17:55                                         ` Ingo Molnar
2004-08-17 18:17                                           ` Paulo Marques
2004-08-14 12:41                               ` Andi Kleen
2004-08-14 13:45                                 ` Paulo Marques
2004-07-26  8:23 preempt-timing-2.6.8-rc1 Ingo Molnar
2004-07-26  8:29 ` preempt-timing-2.6.8-rc1 Lee Revell
2004-07-26  8:35   ` [patch] voluntary-preempt-2.6.8-rc2-J3 Ingo Molnar
2004-07-26  9:00     ` Lee Revell
2004-07-26 12:40       ` Ingo Molnar
2004-07-26 20:47         ` [patch] voluntary-preempt-2.6.8-rc2-J7 Ingo Molnar
2004-07-29 22:26           ` [patch] voluntary-preempt-2.6.8-rc2-M5 Ingo Molnar
2004-08-01 19:30             ` [patch] voluntary-preempt-2.6.8-rc2-O2 Ingo Molnar
2004-08-09 10:46               ` [patch] voluntary-preempt-2.6.8-rc3-O4 Ingo Molnar
2004-08-10 13:26                 ` [patch] voluntary-preempt-2.6.8-rc3-O5 Ingo Molnar
2004-08-12 23:51                   ` [patch] Latency Tracer, voluntary-preempt-2.6.8-rc4-O6 Ingo Molnar
2004-08-13  1:25                     ` Lee Revell
2004-08-13  1:31                       ` Lee Revell
2004-08-13  2:39                         ` Lee Revell
2004-08-13  3:54                           ` Lee Revell
2004-08-13  4:23                             ` Lee Revell
2004-08-13  4:35                               ` Roland Dreier
2004-08-13  4:41                                 ` Lee Revell
2004-08-13  4:46                                   ` Roland Dreier
2004-08-13 10:21                                     ` Ingo Molnar
2004-08-13 10:16                               ` Ingo Molnar
2004-08-13  4:49                     ` Matt Heler
2004-08-13  9:53                       ` Peter Zijlstra
2004-08-13 10:19                         ` Ingo Molnar
2004-08-13 10:23                           ` Peter Zijlstra
2004-08-13  4:58                     ` Lee Revell
2004-08-13 10:22                       ` Ingo Molnar
2004-08-13 18:57                         ` Lee Revell
2004-08-13  5:27                     ` Lee Revell
2004-08-13  5:41                       ` Lee Revell
2004-08-13 10:31                         ` Ingo Molnar
2004-08-13 19:47                           ` Lee Revell
2004-08-16 23:46                           ` Lee Revell
2004-08-17  7:48                             ` Ingo Molnar
2004-08-17  7:56                               ` Lee Revell
2004-08-17 19:18                               ` Theodore Ts'o
2004-08-19 10:54                                 ` Lee Revell
2004-08-19 11:19                                 ` Lee Revell
2004-08-19 19:30                                   ` Theodore Ts'o
2004-08-19 22:32                                     ` Lee Revell
2004-08-19 22:50                                       ` Lee Revell
2004-08-20  0:10                                       ` Lee Revell
2004-08-13  7:40                     ` Lee Revell
2004-08-13 10:42                     ` Florian Schmidt
2004-08-13 10:54                       ` Ingo Molnar
2004-08-13 12:03                         ` Florian Schmidt
2004-08-13 12:03                           ` Ingo Molnar
     [not found]                             ` <20040813145510.60e9e0f3@mango.fruits.de>
2004-08-14  8:57                               ` Ingo Molnar
2004-08-14 11:28                     ` James Courtier-Dutton
2004-08-14 11:51                       ` Ingo Molnar
2004-08-14 12:19                         ` James Courtier-Dutton
2004-08-14 12:32                           ` Ingo Molnar
2004-08-14 16:52                             ` James Courtier-Dutton
2004-08-19  9:10                               ` Ingo Molnar
2004-08-19  9:07                       ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=411D9A2A.1000202@grupopie.com \
    --to=pmarques@grupopie.com \
    --cc=ak@muc.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.