9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] page(1) performance fixes
@ 2022-01-13  1:54 qwx
  2022-01-14 11:30 ` cinap_lenrek
  0 siblings, 1 reply; 5+ messages in thread
From: qwx @ 2022-01-13  1:54 UTC (permalink / raw)
  To: 9front

Hello,

The following patch attempts to improve page(1) performance, a huge
annoyance of mine, especially when files are themselves slow to load.
My benchmark is a t61p where these issues are extremely noticeable.

- fix showpage1 only decrementing proc counter once limit is reached;
this blocked having more than one loadpages process after NPROC calls,
since the next one has to wait until the last has exited, which is why
page(1) always hangs around after every few pages (if memory limit is
large enough anyway, but even with the default)
- allow procs to skip pages currently being loaded by others; this
forced processes to wait for each other when reaching the same page,
which happens all of the time
- (hack) immediately fork NPROC times after adding all pages at
startup to force loading a batch of pages in parallel

Thoughts?  If it's all good, I'd like to commit this.

Thanks,
qwx


diff 6e64d30454f71ecda88dba1bd792e97509115d73 uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -951,7 +951,8 @@
 loadpages(Page *p, int oviewgen)
 {
 	while(p != nil && viewgen == oviewgen){
-		qlock(p);
+		if(!canqlock(p))
+			goto next;
 		loadpage(p);
 		if(viewgen != oviewgen){
 			unloadpage(p);
@@ -974,6 +975,7 @@
 		qunlock(p);
 		if(p != current && imemsize >= imemlimit)
 			break;		/* only one page ahead once we reach the limit */
+	next:
 		if(forward < 0){
 			if(p->up == nil || p->up->down == p)
 				break;
@@ -1309,16 +1311,17 @@
 	writeaddr(p, "/dev/label");
 	current = p;
 	oviewgen = viewgen;
+	if(nproc >= NPROC)
+		waitpid();
 	switch(rfork(RFPROC|RFMEM)){
 	case -1:
 		sysfatal("rfork: %r");
 	case 0:
 		loadpages(p, oviewgen);
+		nproc--;
 		exits(nil);
 	}
-	if(++nproc >= NPROC)
-		if(waitpid() > 0)
-			nproc--;
+	nproc++;
 }
 
 /* recursive display lock, called from main proc only */
@@ -1691,6 +1694,8 @@
 		addpage(root, "stdin", popenfile, strdup("/fd/0"), -1);
 	for(; *argv; argv++)
 		addpage(root, *argv, popenfile, strdup(*argv), -1);
+	for(i=0; i<NPROC; i++)		/* rice */
+		showpage(current);
 
 	drawlock(1);
 	for(;;){

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [9front] page(1) performance fixes
  2022-01-13  1:54 [9front] page(1) performance fixes qwx
@ 2022-01-14 11:30 ` cinap_lenrek
  2022-01-14 17:48   ` qwx
  0 siblings, 1 reply; 5+ messages in thread
From: cinap_lenrek @ 2022-01-14 11:30 UTC (permalink / raw)
  To: 9front

looks good, tho i havnt had the time to test it.

--
cinap

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [9front] page(1) performance fixes
  2022-01-14 11:30 ` cinap_lenrek
@ 2022-01-14 17:48   ` qwx
  2022-01-14 17:54     ` qwx
  0 siblings, 1 reply; 5+ messages in thread
From: qwx @ 2022-01-14 17:48 UTC (permalink / raw)
  To: 9front

diff 6e64d30454f71ecda88dba1bd792e97509115d73 uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -951,7 +951,8 @@
 loadpages(Page *p, int oviewgen)
 {
 	while(p != nil && viewgen == oviewgen){
-		qlock(p);
+		if(!canqlock(p))
+			goto next;
 		loadpage(p);
 		if(viewgen != oviewgen){
 			unloadpage(p);
@@ -974,6 +975,7 @@
 		qunlock(p);
 		if(p != current && imemsize >= imemlimit)
 			break;		/* only one page ahead once we reach the limit */
+	next:
 		if(forward < 0){
 			if(p->up == nil || p->up->down == p)
 				break;
@@ -1309,16 +1311,17 @@
 	writeaddr(p, "/dev/label");
 	current = p;
 	oviewgen = viewgen;
+	if(nproc >= NPROC)
+		waitpid();
 	switch(rfork(RFPROC|RFMEM)){
 	case -1:
 		sysfatal("rfork: %r");
 	case 0:
 		loadpages(p, oviewgen);
+		nproc--;
 		exits(nil);
 	}
-	if(++nproc >= NPROC)
-		if(waitpid() > 0)
-			nproc--;
+	nproc++;
 }
 
 /* recursive display lock, called from main proc only */
@@ -1693,6 +1696,8 @@
 		addpage(root, *argv, popenfile, strdup(*argv), -1);
 
 	drawlock(1);
+	for(i=0; i<NPROC; i++)		/* rice */
+		showpage(current);
 	for(;;){
 		drawlock(0);
 		i=event(&e);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [9front] page(1) performance fixes
  2022-01-14 17:48   ` qwx
@ 2022-01-14 17:54     ` qwx
  2022-01-18  1:18       ` qwx
  0 siblings, 1 reply; 5+ messages in thread
From: qwx @ 2022-01-14 17:54 UTC (permalink / raw)
  To: 9front

Sorry, I somehow got rid of my message on the last email.
That's an updated patch that fixes a locking issue, in case
someone would want to test.  There's another thing I've
noticed that affects performance a lot and that seems easy
to fix, where pages ahead get loaded and unloaded over and
over when switching to the next/previous one.  I don't know
yet if my patch is what is introducing this but I'm looking
into it.

Thanks!
qwx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [9front] page(1) performance fixes
  2022-01-14 17:54     ` qwx
@ 2022-01-18  1:18       ` qwx
  0 siblings, 0 replies; 5+ messages in thread
From: qwx @ 2022-01-18  1:18 UTC (permalink / raw)
  To: 9front

Hello,

Here's another patch improving on the previous one.  The previous
patch allowed readahead procs to skip over pages that others are
processing, but without touching the LRU queue, which frequently
results in pages being unloaded before they've been shown, and ending
up reloading them several times.  Touching the queue any time a page
is looked at in the loadpages loop avoids such issues.

I've also bumped the proc limit which helps avoid delays and hangs, I
don't really see a downside to doing this.

To recap the changes so far:

- fix showpage1 only decrementing proc counter once limit is reached;
this blocked having more than one loadpages process after NPROC calls,
since the next one has to wait until the last has exited
- allow procs to skip pages currently being loaded by others; this
forced processes to wait for each other at the same page
- bump NPROC from 4 to 8
- (hack) immediately fork a few times after adding all pages at
startup to force loading a batch of pages in parallel

I'm still not satisfied with performance.  IMHO this implementation is
fairly fragile, and I haven't found an easy way to fix it.  It might be
a lot easier to do without libevent and using libthread etc, but I'd
like to implement that first to know for sure.

In the mean time, if this looks alright, I'd like to push it.
Thoughts?

Thanks!
qwx


diff 6f9838a6a5b80e0253bdc8fb194ad6f15eb655f5 uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -54,7 +54,7 @@
 char pagespool[] = "/tmp/pagespool.";
 
 enum {
-	NPROC = 4,
+	NPROC = 8,
 	NBUF = 8*1024,
 	NPATH = 1024,
 };
@@ -898,10 +898,6 @@
 {
 	int fd;
 
-	qlock(&lru);
-	llinkhead(p);
-	qunlock(&lru);
-
 	if(p->open != nil && p->image == nil){
 		fd = openpage(p);
 		if(fd >= 0){
@@ -951,7 +947,11 @@
 loadpages(Page *p, int oviewgen)
 {
 	while(p != nil && viewgen == oviewgen){
-		qlock(p);
+		qlock(&lru);
+		llinkhead(p);
+		qunlock(&lru);
+		if(!canqlock(p))
+			goto next;
 		loadpage(p);
 		if(viewgen != oviewgen){
 			unloadpage(p);
@@ -972,6 +972,7 @@
 			unlockdisplay(display);
 		}
 		qunlock(p);
+	next:
 		if(p != current && imemsize >= imemlimit)
 			break;		/* only one page ahead once we reach the limit */
 		if(forward < 0){
@@ -1309,16 +1310,17 @@
 	writeaddr(p, "/dev/label");
 	current = p;
 	oviewgen = viewgen;
+	if(nproc >= NPROC)
+		waitpid();
 	switch(rfork(RFPROC|RFMEM)){
 	case -1:
 		sysfatal("rfork: %r");
 	case 0:
 		loadpages(p, oviewgen);
+		nproc--;
 		exits(nil);
 	}
-	if(++nproc >= NPROC)
-		if(waitpid() > 0)
-			nproc--;
+	nproc++;
 }
 
 /* recursive display lock, called from main proc only */
@@ -1691,6 +1693,8 @@
 		addpage(root, "stdin", popenfile, strdup("/fd/0"), -1);
 	for(; *argv; argv++)
 		addpage(root, *argv, popenfile, strdup(*argv), -1);
+	for(i=0; i<NPROC/4; i++)	/* rice */
+		showpage1(current);
 
 	drawlock(1);
 	for(;;){

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-01-18 10:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13  1:54 [9front] page(1) performance fixes qwx
2022-01-14 11:30 ` cinap_lenrek
2022-01-14 17:48   ` qwx
2022-01-14 17:54     ` qwx
2022-01-18  1:18       ` qwx

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).