Messages in this thread |  | | Date | Sat, 2 Nov 1996 19:58:08 +0200 (EET) | From | Linus Torvalds <> | Subject | Re: X much slower in 2.0.24 than in 1.2.13 |
| |
On Sat, 2 Nov 1996, Chris Evans wrote: > > I can confirm that something 2.0.23->2.0.24 kills x performance... > > Not the world's most scientific test, but with > > time x11perf -all -time 1 -reps 1 > > 2.0.23: 2.37 user, 2.14 system > 2.0.24: 3.73 user, 8.85 system > ^^^^^^^^^^^ > Someone else commented on unreasonably long time spent in "system" rather > than "user".
Ok, anybody want to profile their kernel? It's really pretty simple:
- boot the kernel with the "profile=2" kernel command line (you can use a line like append = "profile=2" in your lilo.conf if you use LILO).
- make sure you have the System.map file that corresponds to your kernel in your root directory (this should be done automatically for you if you use "make zlilo" to create the kernel)
- do a "echo > /proc/profile" as root before starting x11perf to clear out any old profiling information
- run x11perf and afterwards parse the profile information with the supplied program. The output is very easy to decipher..
I'd be interested to hear what the results are, and the anomaly _should_ show up pretty clearly.
Linus
--- /* * Original by Ramon Garcia Fernandez <ramon@juguete.quim.ucm.es> * Hacked by linus */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/fcntl.h> #include <linux/autoconf.h>
#define prof_func "do_no_page"
#define BUFSIZE 1024
#ifndef CONFIG_PROFILE_SHIFT #define CONFIG_PROFILE_SHIFT 2 #endif
struct entry { struct entry * next; unsigned long time; unsigned long address; char name[1]; };
struct entry * list = NULL;
void do_symbol(int time, unsigned long address, char * name) { struct entry * entry = malloc(sizeof(struct entry) + strlen(name)); struct entry ** tmp;
entry->time = time; entry->address = address; strcpy(entry->name, name + (*name == '_')); tmp = &list; while (*tmp) { if ((*tmp)->time > entry->time) break; tmp = &(*tmp)->next; } entry->next = *tmp; *tmp = entry; }
void show_symbols(unsigned long total) { struct entry * entry = list;
while (entry) { printf("%10u %5d.%02d%% %08x %s\n" , entry->time, (entry->time*10000/total) / 100, (entry->time*10000/total) % 100, entry->address, entry->name); entry = entry->next; } }
/* If you do not speak Spanish: * valor_simbolo_actual: current_symbol_value * valor_simbolo_siguiente: next_symbol_value * simbolo_actual: current_symbol * next_symbol: next_symbol * leidos: read (past participle) * total: total */
int main(int argc, char ** argv) { int fp; char * func = prof_func; FILE *kmap; int current_symbol_value , next_symbol_value; char current_symbol[80] , next_symbol[80]; int has_read , total = 0, j;
if (argc == 2) func = argv[1];
fp = open("/proc/profile", O_RDONLY); if (fp < 0) { perror("/proc/profile"); exit(1); } kmap = fopen("/System.map","r"); if (!kmap) { kmap = fopen("/usr/src/linux/System.map","r"); if (!kmap) { perror("System.map"); exit(1); } } fscanf(kmap , "%x %*s %s\n" , ¤t_symbol_value , current_symbol ); fscanf(kmap , "%x %*s %s\n" , &next_symbol_value , next_symbol ); puts(func);
for (;;) { unsigned int buffer[(next_symbol_value - current_symbol_value) >> CONFIG_PROFILE_SHIFT]; unsigned int tiempo = 0;
if (next_symbol_value == current_symbol_value) { strcpy(current_symbol, next_symbol); fscanf(kmap, "%x %*s %s\n", &next_symbol_value, next_symbol); continue; } lseek (fp , sizeof(unsigned int)+current_symbol_value-0xc0100000 , SEEK_SET); has_read = read (fp , buffer , sizeof(buffer) ); for ( j = 0 ; j < has_read/sizeof(unsigned int) ; j++) { if (!strcmp(func, current_symbol)) printf("%08x %d\n", j*4+current_symbol_value, buffer[j]); tiempo += buffer[j]; } if (tiempo != 0) { do_symbol(tiempo, current_symbol_value, current_symbol); total += tiempo; } if (has_read < (next_symbol_value -current_symbol_value) >> CONFIG_PROFILE_SHIFT * sizeof(unsigned long) || next_symbol_value == current_symbol_value ) break; strcpy ( current_symbol , next_symbol ); current_symbol_value = next_symbol_value; fscanf(kmap , "%x %*s %s\n" , &next_symbol_value , next_symbol ); } do_symbol(total, 0, "total"); show_symbols(total); return(0); }
|  |