git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* hosting git on a nfs
@ 2008-11-12  9:29 Thomas Koch
  2008-11-12 10:10 ` Julian Phillips
  2008-11-12 17:36 ` David Brown
  0 siblings, 2 replies; 44+ messages in thread
From: Thomas Koch @ 2008-11-12  9:29 UTC (permalink / raw)
  To: git; +Cc: dabe

Hi,

finally I managed to convince a critical mass of developers (our chief
dev :-) in our company so that we are starting to migrate to GIT.

The final question is, whether GIT will life peacefully on our cluster
fileservers. The GIT repository dir (/var/cache/git) should be mounted
via NFS via PAN on top of DRBD (so I was told).

Are there any known problems with this setup? We're asking, because
there are problems with SVN on such a setup[1].

[1] http://subversion.tigris.org/faq.html#nfs

Best regards,
-- 
Thomas Koch, Software Developer
http://www.koch.ro

Young Media Concepts GmbH
Sonnenstr. 4
CH-8280 Kreuzlingen
Switzerland

Tel    +41 (0)71 / 508 24 86
Fax    +41 (0)71 / 560 53 89
Mobile +49 (0)170 / 753 89 16
Web    www.ymc.ch

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

* Re: hosting git on a nfs
  2008-11-12  9:29 hosting git on a nfs Thomas Koch
@ 2008-11-12 10:10 ` Julian Phillips
  2008-11-12 20:31   ` Brandon Casey
  2008-11-12 17:36 ` David Brown
  1 sibling, 1 reply; 44+ messages in thread
From: Julian Phillips @ 2008-11-12 10:10 UTC (permalink / raw)
  To: Thomas Koch; +Cc: git, dabe

On Wed, 12 Nov 2008, Thomas Koch wrote:

> Hi,
>
> finally I managed to convince a critical mass of developers (our chief
> dev :-) in our company so that we are starting to migrate to GIT.
>
> The final question is, whether GIT will life peacefully on our cluster
> fileservers. The GIT repository dir (/var/cache/git) should be mounted
> via NFS via PAN on top of DRBD (so I was told).
>
> Are there any known problems with this setup? We're asking, because
> there are problems with SVN on such a setup[1].
>
> [1] http://subversion.tigris.org/faq.html#nfs

I've been running git on NFS for years (though it's only NFS exported 
software RAID), and the only issue I've encountered is that it's not quite 
as blisteringly fast as running git on a local disk.

-- 
Julian

  ---
There's something different about us -- different from people of Europe,
Africa, Asia ... a deep and abiding belief in the Easter Bunny.
 		-- G. Gordon Liddy

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

* Re: hosting git on a nfs
  2008-11-12  9:29 hosting git on a nfs Thomas Koch
  2008-11-12 10:10 ` Julian Phillips
@ 2008-11-12 17:36 ` David Brown
  2008-11-12 18:14   ` Linus Torvalds
  1 sibling, 1 reply; 44+ messages in thread
From: David Brown @ 2008-11-12 17:36 UTC (permalink / raw)
  To: Thomas Koch; +Cc: git, dabe

On Wed, Nov 12, 2008 at 10:29:34AM +0100, Thomas Koch wrote:

>finally I managed to convince a critical mass of developers (our chief
>dev :-) in our company so that we are starting to migrate to GIT.
>
>The final question is, whether GIT will life peacefully on our cluster
>fileservers. The GIT repository dir (/var/cache/git) should be mounted
>via NFS via PAN on top of DRBD (so I was told).
>
>Are there any known problems with this setup? We're asking, because
>there are problems with SVN on such a setup[1].

We had occasionally run into locking problems with 1.5.4.x with
renames between different directories.  This should be fixed in
1.6.0.3, but we have since migrated to a server model so I don't have
any way of testing this.

None of these problems ever caused repository corruption, only errors
during fetch/clone that were resolved by repeating the operation.

Using ssh: or git: does seem to be a bit faster than NFS.  The
configuration we did find completely unworkable was using git with the
work tree on NFS.

David

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

* Re: hosting git on a nfs
  2008-11-12 17:36 ` David Brown
@ 2008-11-12 18:14   ` Linus Torvalds
  2008-11-13 18:18     ` J. Bruce Fields
  2008-11-13 18:32     ` James Pickens
  0 siblings, 2 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-12 18:14 UTC (permalink / raw)
  To: David Brown; +Cc: Thomas Koch, git, dabe



On Wed, 12 Nov 2008, David Brown wrote:
> 
> We had occasionally run into locking problems with 1.5.4.x with
> renames between different directories.  This should be fixed in
> 1.6.0.3, but we have since migrated to a server model so I don't have
> any way of testing this.

I suspect it also depends very much on the particular client/server 
combination. Renaming across directories is one of those NFS things that 
some servers don't mind at all.

> The configuration we did find completely unworkable was using git with 
> the work tree on NFS.

Doing an 'lstat()' on every single file in the tree would tend to do that 
to you, yes. Even with a fast network and a good NFS server, we're talking 
millisecond-range latencies, and if your tree has tens of thousands of 
files, you're going to have each "git diff" take several seconds.

NFS metadata caching can help, but not all clients do it, and even clients 
that _do_ do it tend to have rather low timeouts or rather limited cache 
sizes, so doing "git diff" twice may speed up the second one only if it's 
done really back-to-back - if even then.

And once you get used to "git diff" being instantaneous, I don't think 
anybody is ever agan willing to go back to it taking "a few seconds" (and 
depending on speed of network/server and size of project, the "few" can be 
quite many ;)

So putting the work-tree on NFS certainly _works_, but yes, from a 
performance angle it is going to be really irritatingly slower. I don't 
even think the newer versions of NFS will help with directory and 
attribute caching - the delegations are per-file afaik, and there is no 
good support for extending the caching to directories.

That said, I don't think git is any _worse_ than anybody else in the 
"worktree on NFS" model. A "git diff" will still be superior ot a CVS diff 
in every way. It's just that when people compare to their home machines 
where they have the work tree on local disk and aggressively cached, when 
they then use a NFS work-tree, they'll likely be very very disappointed.

				Linus

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

* Re: hosting git on a nfs
  2008-11-12 10:10 ` Julian Phillips
@ 2008-11-12 20:31   ` Brandon Casey
  0 siblings, 0 replies; 44+ messages in thread
From: Brandon Casey @ 2008-11-12 20:31 UTC (permalink / raw)
  To: Julian Phillips; +Cc: Thomas Koch, git, dabe

Julian Phillips wrote:
> On Wed, 12 Nov 2008, Thomas Koch wrote:
> 
>> Hi,
>>
>> finally I managed to convince a critical mass of developers (our chief
>> dev :-) in our company so that we are starting to migrate to GIT.
>>
>> The final question is, whether GIT will life peacefully on our cluster
>> fileservers. The GIT repository dir (/var/cache/git) should be mounted
>> via NFS via PAN on top of DRBD (so I was told).
>>
>> Are there any known problems with this setup? We're asking, because
>> there are problems with SVN on such a setup[1].
>>
>> [1] http://subversion.tigris.org/faq.html#nfs
> 
> I've been running git on NFS for years (though it's only NFS exported
> software RAID), and the only issue I've encountered is that it's not
> quite as blisteringly fast as running git on a local disk.

ditto. (except for the years part)

-brandon

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

* Re: hosting git on a nfs
  2008-11-12 18:14   ` Linus Torvalds
@ 2008-11-13 18:18     ` J. Bruce Fields
  2008-11-13 18:32     ` James Pickens
  1 sibling, 0 replies; 44+ messages in thread
From: J. Bruce Fields @ 2008-11-13 18:18 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: David Brown, Thomas Koch, git, dabe

On Wed, Nov 12, 2008 at 10:14:44AM -0800, Linus Torvalds wrote:
> 
> 
> On Wed, 12 Nov 2008, David Brown wrote:
> > 
> > We had occasionally run into locking problems with 1.5.4.x with
> > renames between different directories.  This should be fixed in
> > 1.6.0.3, but we have since migrated to a server model so I don't have
> > any way of testing this.
> 
> I suspect it also depends very much on the particular client/server 
> combination. Renaming across directories is one of those NFS things that 
> some servers don't mind at all.

On the linux server you want to make sure you're exporting with
no_subtree_check (see "man exports").

> > The configuration we did find completely unworkable was using git with 
> > the work tree on NFS.
> 
> Doing an 'lstat()' on every single file in the tree would tend to do that 
> to you, yes. Even with a fast network and a good NFS server, we're talking 
> millisecond-range latencies, and if your tree has tens of thousands of 
> files, you're going to have each "git diff" take several seconds.
> 
> NFS metadata caching can help, but not all clients do it, and even clients 
> that _do_ do it tend to have rather low timeouts or rather limited cache 
> sizes, so doing "git diff" twice may speed up the second one only if it's 
> done really back-to-back - if even then.
> 
> And once you get used to "git diff" being instantaneous, I don't think 
> anybody is ever agan willing to go back to it taking "a few seconds" (and 
> depending on speed of network/server and size of project, the "few" can be 
> quite many ;)

Yep.

> So putting the work-tree on NFS certainly _works_, but yes, from a 
> performance angle it is going to be really irritatingly slower. I don't 
> even think the newer versions of NFS will help with directory and 
> attribute caching - the delegations are per-file afaik, and there is no 
> good support for extending the caching to directories.

File delegations do cover a file's attributes, so in theory they could
help.  But they're only given out on open.  The upcoming 4.1 spec has a
few improvements here, and it might be worth looking at whether they're
sufficient to make this work.

--b.

> That said, I don't think git is any _worse_ than anybody else in the 
> "worktree on NFS" model. A "git diff" will still be superior ot a CVS diff 
> in every way. It's just that when people compare to their home machines 
> where they have the work tree on local disk and aggressively cached, when 
> they then use a NFS work-tree, they'll likely be very very disappointed.
> 
> 				Linus
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: hosting git on a nfs
  2008-11-12 18:14   ` Linus Torvalds
  2008-11-13 18:18     ` J. Bruce Fields
@ 2008-11-13 18:32     ` James Pickens
  2008-11-13 20:18       ` Linus Torvalds
  1 sibling, 1 reply; 44+ messages in thread
From: James Pickens @ 2008-11-13 18:32 UTC (permalink / raw)
  To: git

Linus Torvalds <torvalds <at> linux-foundation.org> writes:
> Doing an 'lstat()' on every single file in the tree would tend to do that 
> to you, yes. Even with a fast network and a good NFS server, we're talking 
> millisecond-range latencies, and if your tree has tens of thousands of 
> files, you're going to have each "git diff" take several seconds.

Is there any way to improve 'git status' performance on nfs?  I know nothing
about how that code works, but if it's strictly serial, i.e. it waits for the
result of each lstat() before doing the next lstat(), then perhaps it could be
sped up by overlapping the lstat() calls via multi threading.

Reason I ask is that at my work place, using only local disks would be
difficult.  We run lots of long running tests in a server farm, and working on
nfs allows the compute servers to access our data transparently.

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

* Re: hosting git on a nfs
  2008-11-13 18:32     ` James Pickens
@ 2008-11-13 20:18       ` Linus Torvalds
  2008-11-13 21:05         ` Linus Torvalds
  0 siblings, 1 reply; 44+ messages in thread
From: Linus Torvalds @ 2008-11-13 20:18 UTC (permalink / raw)
  To: James Pickens; +Cc: git



On Thu, 13 Nov 2008, James Pickens wrote:
> 
> Is there any way to improve 'git status' performance on nfs?  I know nothing
> about how that code works, but if it's strictly serial, i.e. it waits for the
> result of each lstat() before doing the next lstat(), then perhaps it could be
> sped up by overlapping the lstat() calls via multi threading.

It's fairly doable. "git status" to some degree is actually the worst 
case, since it has to do readdir()'s etc to find new files, but I've 
occasionally considered trying to do a parallel version of the regular 
index file checking where we have the list of files a priori.

That would speed up "git diff" by potentially a big amount (it would also 
speed up git status, just not as much as also doing readdirs in parallel).

However, every time I think about it, I end up looking at my own setup 
which has effectively no parallelism. Sure, in theory parallel reads can 
help even with a local disk, but in practice the potential seek advantage 
is very small, and so I've never really had it as a high priority.

If I were still using NFS (I gave up on it years ago exactly because it 
was so painful for software development - and that was when I was using 
CVS) I'd surely have done it long since.

Bit I'll think about it again. 

		Linus

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

* Re: hosting git on a nfs
  2008-11-13 20:18       ` Linus Torvalds
@ 2008-11-13 21:05         ` Linus Torvalds
  2008-11-13 23:23           ` James Pickens
                             ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-13 21:05 UTC (permalink / raw)
  To: James Pickens, Bruce Fields, Junio C Hamano; +Cc: Git Mailing List



On Thu, 13 Nov 2008, Linus Torvalds wrote:
> 
> If I were still using NFS (I gave up on it years ago exactly because it 
> was so painful for software development - and that was when I was using 
> CVS) I'd surely have done it long since.
> 
> Bit I'll think about it again. 

THIS IS TOTALLY UNTESTED! It's trivial, it's hacky, and it would need to 
be cleaned up before being merged, but I'm not even going to bother 
_trying_ to make it anything cleaner unless somebody can test it on a nice 
NFS setup.

Because it's entirely possible that there are various directory inode 
locks etc that means that doing parallel lookups in the same directory 
won't actually be doing a whole lot. Whatever. It's kind of cute, and it 
really isn't all that many lines of code, and even if it doesn't work due 
to some locking reason, maybe it's worth looking at.

It arbitrarily caps the number of threads to 10, and it has no way to turn 
it on or off. It actually _does_ seem to work in the sense than when 
cached, it can take advantage of the fact that I have a nice multi-core 
thing, but let's face it, it's not really worth it for that reason only. 

Before:

	[torvalds@nehalem linux]$ /usr/bin/time git diff > /dev/null 
	0.03user 0.04system 0:00.07elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k

After:

	0.02user 0.07system 0:00.04elapsed 243%CPU (0avgtext+0avgdata 0maxresident)k
	0inputs+0outputs (0major+2241minor)pagefaults 0swaps

ie it actually did cut elapsed time from 7 hundredths of a second to just 
4. And the CPU usage went from 100% to 243%. Ooooh. Magic.

But it's still hacky as hell. Who has NFS? Can you do the same thing over 
NFS and test it? I'm not going to set up NFS to test this, and as I 
suspected, on a local disk, the cold-cache case makes no difference 
what-so-ever, because whatever seek optimizations can be done are still 
totally irrelevant.

And if there are per-directory locking etc that screws this up, we can 
look at using different heuristics for the lstat() patterns. Right now I 
divvy it up so that thread 0 gets entries 0, 10, 20, 30.. and thread 1 
does entries 1, 11, 21, 31.., but we could easily split it up differently, 
and do 0,1,2,3.. and 1000,1001,1002,1003.. instead. That migth avoid some 
per-directory locks. Dunno.

Anyway, it was kind of fun writing this. The reason it threads so well is 
that all the lstat() code really works on private data already, so there 
are no global data structures that change that need to be worried about. 

So no locking necessary - just fire it up in parallel, and wait for the 
results. We already had everything else in place (ie the per-cache_entry 
flag to say "I've checked this entry on disk").

Of course, if a lot of entries do _not_ match, then this will actually 
generate more work (because we'll do the parallel thing to verify that 
the on-disk version matches, and if it doesn't match, then we'll end up 
re-doing it linearly later more carefully).

			Linus

---
 diff-lib.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/diff-lib.c b/diff-lib.c
index ae96c64..7d972c9 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2005 Junio C Hamano
  */
+#include <pthread.h>
 #include "cache.h"
 #include "quote.h"
 #include "commit.h"
@@ -54,6 +55,70 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
 	return 0;
 }
 
+/* Hacky hack-hack start */
+#define MAX_PARALLEL (10)
+static int parallel_lstats = 1;
+
+struct thread_data {
+	pthread_t pthread;
+	struct index_state *index;
+	struct rev_info *revs;
+	int i, step;
+};
+
+static void *preload_thread(void *_data)
+{
+	int i;
+	struct thread_data *p = _data;
+	struct index_state *index = p->index;
+	struct rev_info *revs = p->revs;
+
+	for (i = p->i; i < index->cache_nr; i += p->step) {
+		struct cache_entry *ce = index->cache[i];
+		struct stat st;
+
+		if (ce_stage(ce))
+			continue;
+		if (ce_uptodate(ce))
+			continue;
+		if (!ce_path_match(ce, revs->prune_data))
+			continue;
+		if (lstat(ce->name, &st))
+			continue;
+		if (ie_match_stat(index, ce, &st, 0))
+			continue;
+		ce_mark_uptodate(ce);
+	}
+	return NULL;
+}
+
+static void preload_uptodate(struct rev_info *revs, struct index_state *index)
+{
+	int i;
+	int threads = index->cache_nr / 100;
+	struct thread_data data[MAX_PARALLEL];
+
+	if (threads < 2)
+		return;
+	if (threads > MAX_PARALLEL)
+		threads = MAX_PARALLEL;
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		p->index = index;
+		p->revs = revs;
+		p->i = i;
+		p->step = threads;
+		if (pthread_create(&p->pthread, NULL, preload_thread, p))
+			die("unable to create threaded lstat");
+	}
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		if (pthread_join(p->pthread, NULL))
+			die("unable to join threaded lstat");
+	}
+}
+/* Hacky hack-hack mostly ends */
+
 int run_diff_files(struct rev_info *revs, unsigned int option)
 {
 	int entries, i;
@@ -68,6 +133,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 	if (diff_unmerged_stage < 0)
 		diff_unmerged_stage = 2;
 	entries = active_nr;
+	if (parallel_lstats)
+		preload_uptodate(revs, &the_index);
 	symcache[0] = '\0';
 	for (i = 0; i < entries; i++) {
 		struct stat st;

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

* Re: hosting git on a nfs
  2008-11-13 21:05         ` Linus Torvalds
@ 2008-11-13 23:23           ` James Pickens
  2008-11-13 23:48             ` Linus Torvalds
  2008-11-13 23:23           ` Julian Phillips
  2008-11-13 23:42           ` Linus Torvalds
  2 siblings, 1 reply; 44+ messages in thread
From: James Pickens @ 2008-11-13 23:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Bruce Fields, Junio C Hamano, Git Mailing List

On Thu, Nov 13, 2008, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> But it's still hacky as hell. Who has NFS? Can you do the same thing over
> NFS and test it? I'm not going to set up NFS to test this, and as I
> suspected, on a local disk, the cold-cache case makes no difference
> what-so-ever, because whatever seek optimizations can be done are still
> totally irrelevant.

I'm trying to test this and so far I'm not seeing any effect.  The
timings are all over the map, but the average time is about the same as
before.  If I run 'git status' over and over without pausing in between,
it runs very fast, so I guess the client is caching some things for a
short time.  Here are the timings I got by running git 1.6.0.4 and
1.6.0.4 plus this patch, alternating between them and sleeping for 60
seconds after each run:

Git 1.6.0.4:
4.83
4.47
4.54
9.04
5.28
4.33
6.40
13.71
4.51
5.90

Git 1.6.0.4 plus patch:
7.82
10.94
4.61
5.06
5.59
5.22
4.65
5.58
6.70
9.15

I'll play around with the code and see if I figure anything out.

In case it matters, I'm using a 4 core machine with a fairly old kernel:

$ uname -r
2.6.5-7.287.3.PTF.363939.1-smp

BTW thanks a lot for working on it.  I was expecting a response along
the lines of "it's possible but would require extensive code changes so
it's not likely to happen", and instead a patch was posted only a few
hours later.  Maybe I should ask for all those other upgrades I've had
in mind... ;-)

James

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

* Re: hosting git on a nfs
  2008-11-13 21:05         ` Linus Torvalds
  2008-11-13 23:23           ` James Pickens
@ 2008-11-13 23:23           ` Julian Phillips
  2008-11-13 23:42           ` Linus Torvalds
  2 siblings, 0 replies; 44+ messages in thread
From: Julian Phillips @ 2008-11-13 23:23 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List

On Thu, 13 Nov 2008, Linus Torvalds wrote:

> Before:
>
> 	[torvalds@nehalem linux]$ /usr/bin/time git diff > /dev/null
> 	0.03user 0.04system 0:00.07elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
>
> After:
>
> 	0.02user 0.07system 0:00.04elapsed 243%CPU (0avgtext+0avgdata 0maxresident)k
> 	0inputs+0outputs (0major+2241minor)pagefaults 0swaps
>
> ie it actually did cut elapsed time from 7 hundredths of a second to just
> 4. And the CPU usage went from 100% to 243%. Ooooh. Magic.
>
> But it's still hacky as hell. Who has NFS? Can you do the same thing over
> NFS and test it? I'm not going to set up NFS to test this, and as I
> suspected, on a local disk, the cold-cache case makes no difference
> what-so-ever, because whatever seek optimizations can be done are still
> totally irrelevant.

The timings seem to vary quite a bit (not really a surprise with a network 
involved ;), but the patch definately makes things faster:

master:

jp3@kaos: linux-2.6(master)>/usr/bin/time ~/bin/git diff > /dev/null
0.01user 0.19system 0:02.50elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+1766minor)pagefaults 0swaps

master + patch:

jp3@kaos: linux-2.6(master)>/usr/bin/time ~/bin/git diff > /dev/null
0.02user 0.88system 0:00.96elapsed 93%CPU (0avgtext+0avgdata 
0maxresident)k
0inputs+0outputs (0major+1783minor)pagefaults 0swaps

seems to be approximately twice as fast?

-- 
Julian

  ---
<nelchael> "XML is like violence, if it doesn't solve the problem, just
  use more."
* nelchael hides

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

* Re: hosting git on a nfs
  2008-11-13 21:05         ` Linus Torvalds
  2008-11-13 23:23           ` James Pickens
  2008-11-13 23:23           ` Julian Phillips
@ 2008-11-13 23:42           ` Linus Torvalds
  2008-11-14  0:04             ` Julian Phillips
  2008-11-14  0:14             ` Brandon Casey
  2 siblings, 2 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-13 23:42 UTC (permalink / raw)
  To: James Pickens, Bruce Fields, Junio C Hamano; +Cc: Git Mailing List



On Thu, 13 Nov 2008, Linus Torvalds wrote:
>
> And if there are per-directory locking etc that screws this up, we can 
> look at using different heuristics for the lstat() patterns. Right now I 
> divvy it up so that thread 0 gets entries 0, 10, 20, 30.. and thread 1 
> does entries 1, 11, 21, 31.., but we could easily split it up differently, 
> and do 0,1,2,3.. and 1000,1001,1002,1003.. instead. That migth avoid some 
> per-directory locks. Dunno.

Yeah, I just checked. We really should to the lookups in clusters, because 
yes, we do have directory locks that limit parallel lookups in the same 
directory, so to get good parallelism you want to look up in different 
places.

Admittedly that's really a Linux kernel deficiency, and I'd love to fix it 
(in the long run), but we optimize file lookup for the common (cached) 
case, and the uncommon case of parallel misses in the same directory has 
been written for simplicity and robustness.

So don't even bother trying the previous patch, even if it might work. At 
least not on Linux. Try this one instead, which does the parallel things 
in batches, so that we hopefully hit different directories.

Parallelism is hard. 

The good news is that I seem to actualluy see a bit of a win from this 
even on a disk, now that the kernel doesn't serialize things. So it may 
be worth it. So I have some hope that it actually helps on NFS too. 
The numbers for five runs (with clearing of the caches in between, of 
course) are:

Before:

	0.01user 0.23system 0:10.87elapsed 2%CPU
	0.04user 0.19system 0:10.86elapsed 2%CPU
	0.03user 0.26system 0:10.82elapsed 2%CPU
	0.02user 0.27system 0:12.67elapsed 2%CPU
	0.01user 0.22system 0:10.86elapsed 2%CPU

After:

	0.03user 0.26system 0:07.88elapsed 3%CPU
	0.02user 0.25system 0:07.63elapsed 3%CPU
	0.01user 0.26system 0:08.62elapsed 3%CPU
	0.01user 0.26system 0:07.27elapsed 3%CPU
	0.05user 0.28system 0:08.61elapsed 3%CPU

so it really does seem like it has possibly given a 30% improvement in 
cold-cache performance even on a disk. 

NOTE NOTE NOTE! This is still a total hack. If this was done properly, we 
would do the "preload_uptodate()" thing when we load the cache for all the 
different programs where it can matter, not just the one special case 
place. So see this as a proof-of-concept, nothing more.

		Linus

---
 diff-lib.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/diff-lib.c b/diff-lib.c
index ae96c64..83c180d 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2005 Junio C Hamano
  */
+#include <pthread.h>
 #include "cache.h"
 #include "quote.h"
 #include "commit.h"
@@ -54,6 +55,77 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
 	return 0;
 }
 
+/* Hacky hack-hack start */
+#define MAX_PARALLEL (10)
+static int parallel_lstats = 1;
+
+struct thread_data {
+	pthread_t pthread;
+	struct index_state *index;
+	const char **pathspec;
+	int offset, nr;
+};
+
+static void *preload_thread(void *_data)
+{
+	int nr;
+	struct thread_data *p = _data;
+	struct index_state *index = p->index;
+	struct cache_entry **cep = index->cache + p->offset;
+
+	nr = p->nr;
+	if (nr + p->offset > index->cache_nr)
+		nr = index->cache_nr - p->offset;
+
+	do {
+		struct cache_entry *ce = *cep++;
+		struct stat st;
+
+		if (ce_stage(ce))
+			continue;
+		if (ce_uptodate(ce))
+			continue;
+		if (!ce_path_match(ce, p->pathspec))
+			continue;
+		if (lstat(ce->name, &st))
+			continue;
+		if (ie_match_stat(index, ce, &st, 0))
+			continue;
+		ce_mark_uptodate(ce);
+	} while (--nr > 0);
+	return NULL;
+}
+
+static void preload_uptodate(const char **pathspec, struct index_state *index)
+{
+	int i, work, offset;
+	int threads = index->cache_nr / 100;
+	struct thread_data data[MAX_PARALLEL];
+
+	if (threads < 2)
+		return;
+	if (threads > MAX_PARALLEL)
+		threads = MAX_PARALLEL;
+	offset = 0;
+	work = (index->cache_nr + threads - 1) / threads;
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		p->index = index;
+		p->pathspec = pathspec;
+		p->offset = offset;
+		p->nr = work;
+		offset += work;
+		if (pthread_create(&p->pthread, NULL, preload_thread, p))
+			die("unable to create threaded lstat");
+	}
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		if (pthread_join(p->pthread, NULL))
+			die("unable to join threaded lstat");
+	}
+}
+/* Hacky hack-hack mostly ends */
+
 int run_diff_files(struct rev_info *revs, unsigned int option)
 {
 	int entries, i;
@@ -68,6 +140,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 	if (diff_unmerged_stage < 0)
 		diff_unmerged_stage = 2;
 	entries = active_nr;
+	if (parallel_lstats)
+		preload_uptodate(revs->prune_data, &the_index);
 	symcache[0] = '\0';
 	for (i = 0; i < entries; i++) {
 		struct stat st;

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

* Re: hosting git on a nfs
  2008-11-13 23:23           ` James Pickens
@ 2008-11-13 23:48             ` Linus Torvalds
  0 siblings, 0 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-13 23:48 UTC (permalink / raw)
  To: James Pickens; +Cc: Bruce Fields, Junio C Hamano, Git Mailing List



On Thu, 13 Nov 2008, James Pickens wrote:
> 
> I'm trying to test this and so far I'm not seeing any effect.

Ok, try my second version. The first version would get _some_ parallelism, 
but very little due to all the threads often trying to just look up in the 
same directory. The second version should hopefully have less of that 
effect.

Also, under Linux, try it with caches cleared in between runs, so that you 
can avoid any issues of the Linux client caching the directory lookup data 
(which linux _will_ do - I think the default timeout is 30 seconds or 
something like that):

	echo 3 > /proc/sys/vm/drop_caches ; time git diff

which should hopefully get you more reliable timings.

			Linus

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

* Re: hosting git on a nfs
  2008-11-13 23:42           ` Linus Torvalds
@ 2008-11-14  0:04             ` Julian Phillips
  2008-11-14  0:14             ` Brandon Casey
  1 sibling, 0 replies; 44+ messages in thread
From: Julian Phillips @ 2008-11-14  0:04 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List

On Thu, 13 Nov 2008, Linus Torvalds wrote:

> The good news is that I seem to actualluy see a bit of a win from this
> even on a disk, now that the kernel doesn't serialize things. So it may
> be worth it. So I have some hope that it actually helps on NFS too.
> The numbers for five runs (with clearing of the caches in between, of
> course) are:
>
> Before:
>
> 	0.01user 0.23system 0:10.87elapsed 2%CPU
> 	0.04user 0.19system 0:10.86elapsed 2%CPU
> 	0.03user 0.26system 0:10.82elapsed 2%CPU
> 	0.02user 0.27system 0:12.67elapsed 2%CPU
> 	0.01user 0.22system 0:10.86elapsed 2%CPU
>
> After:
>
> 	0.03user 0.26system 0:07.88elapsed 3%CPU
> 	0.02user 0.25system 0:07.63elapsed 3%CPU
> 	0.01user 0.26system 0:08.62elapsed 3%CPU
> 	0.01user 0.26system 0:07.27elapsed 3%CPU
> 	0.05user 0.28system 0:08.61elapsed 3%CPU
>
> so it really does seem like it has possibly given a 30% improvement in
> cold-cache performance even on a disk.

On an NFS kernel checkout I get the following elapsed times:

master:

0:02.78
0:02.70
0:02.43
0:02.28
0:02.71
0:02.80
0:02.60
0:02.06
0:02.00

master + new patch:

0:00.77
0:00.83
0:01.02
0:00.77
0:00.91
0:00.78
0:00.78
0:01.09
0:01.00

-- 
Julian

  ---
There are no accidents whatsoever in the universe.
 		-- Baba Ram Dass

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

* Re: hosting git on a nfs
  2008-11-13 23:42           ` Linus Torvalds
  2008-11-14  0:04             ` Julian Phillips
@ 2008-11-14  0:14             ` Brandon Casey
  2008-11-14  0:38               ` Linus Torvalds
  1 sibling, 1 reply; 44+ messages in thread
From: Brandon Casey @ 2008-11-14  0:14 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List



Second version.


Hot cache (over NFS):

Before:

0.01user 0.11system 0:00.13elapsed 95%CPU
0.01user 0.11system 0:00.13elapsed 96%CPU
0.01user 0.12system 0:00.13elapsed 97%CPU

After:

0.01user 0.09system 0:00.11elapsed 95%CPU
0.01user 0.09system 0:00.11elapsed 95%CPU
0.01user 0.09system 0:00.11elapsed 95%CPU


Cold cache* (over NFS):

Before:

0.01user 0.31system 0:04.40elapsed 7%CPU
0.01user 0.31system 0:06.47elapsed 5%CPU
0.01user 0.26system 0:04.19elapsed 6%CPU
0.01user 0.30system 0:04.99elapsed 6%CPU

After:

0.01user 0.46system 0:01.39elapsed 34%CPU
0.01user 0.41system 0:00.88elapsed 47%CPU
0.01user 0.45system 0:01.16elapsed 40%CPU
0.01user 0.45system 0:00.99elapsed 47%CPU
0.01user 0.45system 0:01.02elapsed 45%CPU


* Note: I can't do 'echo 3 > /proc/sys/vm/drop_caches', so cold
  cache means 'sleep 60' between git diff (30 wasn't long enough).

-brandon

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

* Re: hosting git on a nfs
  2008-11-14  0:14             ` Brandon Casey
@ 2008-11-14  0:38               ` Linus Torvalds
  2008-11-14  0:59                 ` Pieter de Bie
  2008-11-14  1:15                 ` Linus Torvalds
  0 siblings, 2 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-14  0:38 UTC (permalink / raw)
  To: Brandon Casey
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List



On Thu, 13 Nov 2008, Brandon Casey wrote:
>
> Cold cache* (over NFS):
> 
> Before:
> 
> 0.01user 0.31system 0:04.40elapsed 7%CPU
> 0.01user 0.31system 0:06.47elapsed 5%CPU
> 0.01user 0.26system 0:04.19elapsed 6%CPU
> 0.01user 0.30system 0:04.99elapsed 6%CPU
> 
> After:
> 
> 0.01user 0.46system 0:01.39elapsed 34%CPU
> 0.01user 0.41system 0:00.88elapsed 47%CPU
> 0.01user 0.45system 0:01.16elapsed 40%CPU
> 0.01user 0.45system 0:00.99elapsed 47%CPU
> 0.01user 0.45system 0:01.02elapsed 45%CPU

Ok, both you and Julian do seem to be getting a nice speedup from this.

I'll clean it up a bit and make a less hacky version. And I'll try to make 
it work for "git status" and friends too.

		Linus

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

* Re: hosting git on a nfs
  2008-11-14  0:38               ` Linus Torvalds
@ 2008-11-14  0:59                 ` Pieter de Bie
  2008-11-14  1:15                 ` Linus Torvalds
  1 sibling, 0 replies; 44+ messages in thread
From: Pieter de Bie @ 2008-11-14  0:59 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Brandon Casey, James Pickens, Bruce Fields, Junio C Hamano,
	Git Mailing List


On Nov 14, 2008, at 1:38 AM, Linus Torvalds wrote:

> Ok, both you and Julian do seem to be getting a nice speedup from  
> this.
>
> I'll clean it up a bit and make a less hacky version. And I'll try  
> to make
> it work for "git status" and friends too.

I have two more datapoints.

The first is OS X 10.5 on a local HFS repository. git.git goes down  
from ~70 to ~63ms and mozilla's repository (30000) files goes from  
~350ms to ~230ms (yeah, HFS sucks).

Using AFP for the same repositories, the first goes down from ~80 to  
~67ms, the second from ~70 seconds to ~50 seconds, which is a nice  
speedup :)

- Pieter

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

* Re: hosting git on a nfs
  2008-11-14  0:38               ` Linus Torvalds
  2008-11-14  0:59                 ` Pieter de Bie
@ 2008-11-14  1:15                 ` Linus Torvalds
  2008-11-14  3:33                   ` James Pickens
                                     ` (3 more replies)
  1 sibling, 4 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-14  1:15 UTC (permalink / raw)
  To: Brandon Casey
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List



On Thu, 13 Nov 2008, Linus Torvalds wrote:
> 
> I'll clean it up a bit and make a less hacky version. And I'll try to make 
> it work for "git status" and friends too.

Ok, this is a no-longer-totally-hacky thing, which also adds support for 
doing the same for "git status". I haven't actually done any timings, but 
the preload algorithm is all the same. The interface is just a much more 
natural one.

NOTE NOTE NOTE! It may not be totally hacky, but it's still not 
"finished". There's a few more things to look at:

 - maybe there are other users of "read_cache()" that want to do the 
   preloading. I just did "git diff" and "git status" (where the stuff 
   that "git commit" does falls out of the status changes)

 - I do think the thing should be more configurable. The "ten threads" 
   approach makes no sense for people who have single-core CPU's and tend 
   to have their trees cached - it will just slow things down for that 
   case. So there should probably be some config option to turn this on 
   and off.

 - It would be really cool to find some way to automatically notice when 
   the tree is hot-cached and we might as well just be linear. I don't 
   know exactly what it might be, but one of the nice things is that the 
   preloading is _entirely_ optimistic, and we could just stop it in the 
   middle if we notice that there's no upside.

 - Somebody else should take a look at it in general. It may work, but 
   maybe there's something stupid I'm doing, or maybe somebody else can 
   come up with a clever thing.

So I think this is probably my last version for now, and let's see if 
others can find improvements. I'm not ashamed of it any more. There's 
still a "Hacky hack start" comment, it's about the whole config thing. 

			Linus

---
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 13 Nov 2008 16:36:30 -0800
Subject: [PATCH] Add cache preload facility

This can do the lstat() storm in parallel, giving potentially much
improved performance for cold-cache cases or things like NFS that have
weak metadata caching.

Just use "read_cache_preload()" instead of "read_cache()" to force an
optimistic preload of the index stat data.  The function takes a
pathspec as its argument, allowing us to preload only the relevant
portion of the index.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 Makefile             |    1 +
 builtin-commit.c     |    8 ++--
 builtin-diff-files.c |    4 +-
 builtin-diff.c       |    8 ++--
 cache.h              |    2 +
 preload-index.c      |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index 920cb42..8387005 100644
--- a/Makefile
+++ b/Makefile
@@ -495,6 +495,7 @@ LIB_OBJS += write_or_die.o
 LIB_OBJS += ws.o
 LIB_OBJS += wt-status.o
 LIB_OBJS += xdiff-interface.o
+LIB_OBJS += preload-index.o
 
 BUILTIN_OBJS += builtin-add.o
 BUILTIN_OBJS += builtin-annotate.o
diff --git a/builtin-commit.c b/builtin-commit.c
index 93ca496..90b976e 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -225,18 +225,18 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
 
 	if (interactive) {
 		interactive_add(argc, argv, prefix);
-		if (read_cache() < 0)
+		if (read_cache_preload(NULL) < 0)
 			die("index file corrupt");
 		commit_style = COMMIT_AS_IS;
 		return get_index_file();
 	}
 
-	if (read_cache() < 0)
-		die("index file corrupt");
-
 	if (*argv)
 		pathspec = get_pathspec(prefix, argv);
 
+	if (read_cache_preload(pathspec) < 0)
+		die("index file corrupt");
+
 	/*
 	 * Non partial, non as-is commit.
 	 *
diff --git a/builtin-diff-files.c b/builtin-diff-files.c
index 2b578c7..5b64011 100644
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
@@ -59,8 +59,8 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
 	    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))
 		rev.combine_merges = rev.dense_combined_merges = 1;
 
-	if (read_cache() < 0) {
-		perror("read_cache");
+	if (read_cache_preload(rev.diffopt.paths) < 0) {
+		perror("read_cache_preload");
 		return -1;
 	}
 	result = run_diff_files(&rev, options);
diff --git a/builtin-diff.c b/builtin-diff.c
index 82d4dda..b9a2b37 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -134,8 +134,8 @@ static int builtin_diff_index(struct rev_info *revs,
 	    revs->max_count != -1 || revs->min_age != -1 ||
 	    revs->max_age != -1)
 		usage(builtin_diff_usage);
-	if (read_cache() < 0) {
-		perror("read_cache");
+	if (read_cache_preload(revs->diffopt.paths) < 0) {
+		perror("read_cache_preload");
 		return -1;
 	}
 	return run_diff_index(revs, cached);
@@ -234,8 +234,8 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
 		revs->combine_merges = revs->dense_combined_merges = 1;
 
 	setup_work_tree();
-	if (read_cache() < 0) {
-		perror("read_cache");
+	if (read_cache_preload(revs->diffopt.paths) < 0) {
+		perror("read_cache_preload");
 		return -1;
 	}
 	result = run_diff_files(revs, options);
diff --git a/cache.h b/cache.h
index 6be60ea..c7b69e8 100644
--- a/cache.h
+++ b/cache.h
@@ -262,6 +262,7 @@ static inline void remove_name_hash(struct cache_entry *ce)
 
 #define read_cache() read_index(&the_index)
 #define read_cache_from(path) read_index_from(&the_index, (path))
+#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec))
 #define is_cache_unborn() is_index_unborn(&the_index)
 #define read_cache_unmerged() read_index_unmerged(&the_index)
 #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd))
@@ -368,6 +369,7 @@ extern int init_db(const char *template_dir, unsigned int flags);
 
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
+extern int read_index_preload(struct index_state *, const char **pathspec);
 extern int read_index_from(struct index_state *, const char *path);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
diff --git a/preload-index.c b/preload-index.c
new file mode 100644
index 0000000..e322c27
--- /dev/null
+++ b/preload-index.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 Linus Torvalds
+ */
+#include <pthread.h>
+#include "cache.h"
+
+/* Hacky hack-hack start */
+#define MAX_PARALLEL (100)
+int parallel_lstats = 1;
+
+struct thread_data {
+	pthread_t pthread;
+	struct index_state *index;
+	const char **pathspec;
+	int offset, nr;
+};
+
+static void *preload_thread(void *_data)
+{
+	int nr;
+	struct thread_data *p = _data;
+	struct index_state *index = p->index;
+	struct cache_entry **cep = index->cache + p->offset;
+
+	nr = p->nr;
+	if (nr + p->offset > index->cache_nr)
+		nr = index->cache_nr - p->offset;
+
+	do {
+		struct cache_entry *ce = *cep++;
+		struct stat st;
+
+		if (ce_stage(ce))
+			continue;
+		if (ce_uptodate(ce))
+			continue;
+		if (!ce_path_match(ce, p->pathspec))
+			continue;
+		if (lstat(ce->name, &st))
+			continue;
+		if (ie_match_stat(index, ce, &st, 0))
+			continue;
+		ce_mark_uptodate(ce);
+	} while (--nr > 0);
+	return NULL;
+}
+
+static void preload_index(struct index_state *index, const char **pathspec)
+{
+	int i, work, offset;
+	int threads = index->cache_nr / 100;
+	struct thread_data data[MAX_PARALLEL];
+
+	if (threads < 2)
+		return;
+	if (threads > MAX_PARALLEL)
+		threads = MAX_PARALLEL;
+	offset = 0;
+	work = (index->cache_nr + threads - 1) / threads;
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		p->index = index;
+		p->pathspec = pathspec;
+		p->offset = offset;
+		p->nr = work;
+		offset += work;
+		if (pthread_create(&p->pthread, NULL, preload_thread, p))
+			die("unable to create threaded lstat");
+	}
+	for (i = 0; i < threads; i++) {
+		struct thread_data *p = data+i;
+		if (pthread_join(p->pthread, NULL))
+			die("unable to join threaded lstat");
+	}
+}
+
+int read_index_preload(struct index_state *index, const char **pathspec)
+{
+	int retval = read_index(index);
+
+	preload_index(index, pathspec);
+	return retval;
+}

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

* Re: hosting git on a nfs
  2008-11-14  1:15                 ` Linus Torvalds
@ 2008-11-14  3:33                   ` James Pickens
  2008-11-14  5:01                     ` Linus Torvalds
  2008-11-14 13:01                   ` Michael J Gruber
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 44+ messages in thread
From: James Pickens @ 2008-11-14  3:33 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Brandon Casey, Bruce Fields, Junio C Hamano, Git Mailing List

On Thu, Nov 13, 2008 at 6:15 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>  - maybe there are other users of "read_cache()" that want to do the
>   preloading. I just did "git diff" and "git status" (where the stuff
>   that "git commit" does falls out of the status changes)

I wonder if there are other completely different parts of git that could
benefit from multi threading when the work tree is on nfs?  I'm thinking
specifically of 'git checkout', since while testing this patch I
happened to do a 'git pull' that resulted in several thousand new files
being created, and the "Checking out files" part took *forever* to run.

And FWIW, I timed 50 iterations of 'git diff', and the average runtime
dropped from 11.7s to 2.8s after this patch.  A nice improvement.

James

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

* Re: hosting git on a nfs
  2008-11-14  3:33                   ` James Pickens
@ 2008-11-14  5:01                     ` Linus Torvalds
  0 siblings, 0 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-14  5:01 UTC (permalink / raw)
  To: James Pickens
  Cc: Brandon Casey, Bruce Fields, Junio C Hamano, Git Mailing List



On Thu, 13 Nov 2008, James Pickens wrote:
> 
> I wonder if there are other completely different parts of git that could
> benefit from multi threading when the work tree is on nfs?

I'm sure there are. That said, threading things is usually really quite 
painful. The only reason this preloading was easy to do was that we really 
had all the data structures laid out beautifully for this, and I had spent 
a lot of effort earlier on a whole series of "avoid duplicate lstat()" 
changes, which gave us that whole ce_uptodate() thing, and all normal 
cases already taking advantage of it, and the "uptodate" bit being 
percolated along all the paths.

If it hadn't been for that, it would have been much nastier to do.

As it was, there was literally just a simple little extra phase to fill in 
all teh data structures that we already had set up in parallel.

> I'm thinking specifically of 'git checkout', since while testing this 
> patch I happened to do a 'git pull' that resulted in several thousand 
> new files being created, and the "Checking out files" part took 
> *forever* to run.

Now, the good news is that the actual work-tree part of checking things 
out is probably pretty amenable to the same kind of parallelization, for 
largely the same reasons: the whole checking out thing is already done in 
multiple phases with all error handling done before-hand. So we will have 
built up all our data structures earlier, and set the CE_UPDATE bit, and 
then there's just a final "push it all out" phase.

So CE_UPTODATE and CE_UPDATE are really very similar in that sense - 
except at opposite ends of the pipeline. The CE_UPTODATE bit marks a name 
entry as matching the filesystem data (and allows all later phases to 
avoid doing the expensive lstat()s), while the CE_UPDATE (and CE_REMOVE) 
bits allow us to do all our complex work in-memory without committing it 
to disk, and then we push it out in one go.

So if you want to multi-thread checkout, you literally need to just thread 
the last for-loop in unpack-trees.c:check_updates() (the CE_UPDATE loop 
that does "checkout_entry()" over the whole index). 

> And FWIW, I timed 50 iterations of 'git diff', and the average runtime
> dropped from 11.7s to 2.8s after this patch.  A nice improvement.

Very impressive. That said, I suspect you get a "superlinear" improvement 
because once it gets faster, the kernel cache also works better, since you 
can do more loops without having the NFS attributes time out.

Whether that kind of effect happens much in actual practice is debatable, 
although it's quite possible that it will work the same way in some 
scripting schenarios.

			Linus

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

* Re: hosting git on a nfs
  2008-11-14  1:15                 ` Linus Torvalds
  2008-11-14  3:33                   ` James Pickens
@ 2008-11-14 13:01                   ` Michael J Gruber
  2008-11-14 14:31                   ` Kyle Moffett
  2008-11-14 18:32                   ` Brandon Casey
  3 siblings, 0 replies; 44+ messages in thread
From: Michael J Gruber @ 2008-11-14 13:01 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Brandon Casey, James Pickens, Bruce Fields, Junio C Hamano,
	Git Mailing List

Linus Torvalds venit, vidit, dixit 14.11.2008 02:15:
> 
> On Thu, 13 Nov 2008, Linus Torvalds wrote:
>> I'll clean it up a bit and make a less hacky version. And I'll try to make 
>> it work for "git status" and friends too.
> 
> Ok, this is a no-longer-totally-hacky thing, which also adds support for 
> doing the same for "git status". I haven't actually done any timings, but 
> the preload algorithm is all the same. The interface is just a much more 
> natural one.
> 
> NOTE NOTE NOTE! It may not be totally hacky, but it's still not 
> "finished". There's a few more things to look at:

Doing nicely already. Over here, cold cache (i.e. sleep 70) "git status"
goes from 0.8s to around 0.4s. Nice. Hot cache goes from 0.18s to 0.23s.
This is really worthwhile if you hack for more than 60s between
diffs/stats ;)

This is already with the server doing some caching (first status was 8s
or so; hardly reproducible), which I can't control.

Michael

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

* Re: hosting git on a nfs
  2008-11-14  1:15                 ` Linus Torvalds
  2008-11-14  3:33                   ` James Pickens
  2008-11-14 13:01                   ` Michael J Gruber
@ 2008-11-14 14:31                   ` Kyle Moffett
  2008-11-14 18:32                   ` Brandon Casey
  3 siblings, 0 replies; 44+ messages in thread
From: Kyle Moffett @ 2008-11-14 14:31 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Brandon Casey, James Pickens, Bruce Fields, Junio C Hamano,
	Git Mailing List

On Thu, Nov 13, 2008 at 8:15 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>  - It would be really cool to find some way to automatically notice when
>   the tree is hot-cached and we might as well just be linear. I don't
>   know exactly what it might be, but one of the nice things is that the
>   preloading is _entirely_ optimistic, and we could just stop it in the
>   middle if we notice that there's no upside.

Perhaps, rather... notice when the tree is *cold*-cached.  At that
point you're already in a pseudo-slowpath and starting several threads
won't be noticeable at all compared to the time savings.  You could
probably very easily do that by keeping track of the time as you start
with the normal single-threaded scan of directory entries.  If the
entries are all equally slow/fast, there most likely won't be any
benefit at all to spawning extra threads.  You might use some cutoff
on number of entries to test before you assume everything is hot and
stop worrying about the time.  If there's a lot of variability in the
first few thousand then it means some caches are cold and spawning
extra threads will probably help.

Cheers,
Kyle Moffett

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

* Re: hosting git on a nfs
  2008-11-14  1:15                 ` Linus Torvalds
                                     ` (2 preceding siblings ...)
  2008-11-14 14:31                   ` Kyle Moffett
@ 2008-11-14 18:32                   ` Brandon Casey
  2008-11-14 19:23                     ` Linus Torvalds
  3 siblings, 1 reply; 44+ messages in thread
From: Brandon Casey @ 2008-11-14 18:32 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List

Linus Torvalds wrote:
> 
> On Thu, 13 Nov 2008, Linus Torvalds wrote:
>> I'll clean it up a bit and make a less hacky version. And I'll try to make 
>> it work for "git status" and friends too.
> 
> Ok, this is a no-longer-totally-hacky thing, which also adds support for 
> doing the same for "git status". I haven't actually done any timings, but 
> the preload algorithm is all the same. The interface is just a much more 
> natural one.

git status > /dev/null

Before:

   0.06user 0.37system 0:03.04elapsed 14%CPU
   0.07user 0.36system 0:03.25elapsed 13%CPU
   0.07user 0.36system 0:03.08elapsed 14%CPU

After:

   0.06user 0.53system 0:01.02elapsed 58%CPU
   0.05user 0.54system 0:01.01elapsed 58%CPU
   0.06user 0.52system 0:01.04elapsed 57%CPU


git diff > /dev/null

Before:

   0.02user 0.31system 0:02.88elapsed 11%CPU
   0.01user 0.32system 0:02.53elapsed 13%CPU
   0.01user 0.28system 0:02.78elapsed 10%CPU

After:

   0.01user 0.47system 0:00.52elapsed 92%CPU
   0.01user 0.48system 0:00.52elapsed 94%CPU
   0.01user 0.47system 0:00.54elapsed 88%CPU


I have no explanation for why the diff numbers are different from yesterday.
Could be that there was some nightly cron job running last night which
slowed things down. Still, the same ~5x speedup is observed!

Wow! Thanks!

-brandon

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

* Re: hosting git on a nfs
  2008-11-14 18:32                   ` Brandon Casey
@ 2008-11-14 19:23                     ` Linus Torvalds
  2008-11-14 20:14                       ` Junio C Hamano
  2008-11-15 12:08                       ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
  0 siblings, 2 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-14 19:23 UTC (permalink / raw)
  To: Brandon Casey
  Cc: James Pickens, Bruce Fields, Junio C Hamano, Git Mailing List



On Fri, 14 Nov 2008, Brandon Casey wrote:
> 
> I have no explanation for why the diff numbers are different from 
> yesterday. Could be that there was some nightly cron job running last 
> night which slowed things down. Still, the same ~5x speedup is observed!

One of the things I changed (inadvertently - it was just meant to be a 
test) was that the last patch had MAX_PARALLEL set to 100 rather than 10. 
That's definitely overkill.

I also think the thread cost was wrong: it did

	threads = index->cache_nr / 100;

to give a first-order "how many threads do we want", but the thread 
startup is likely to be higher than 100 lstat calls, so we probably want 
fewer threads than that. It doesn't much matter for something like the 
Linux kernel, where there are so many files that we'll end up maxing out 
the threads anyway, but for smaller projects, I suspect a thread cost of 
"one thread per 500 files" is more reasonable. You almost certainly don't 
want to thread anything at all for fewer than a few hundred files.

So here's a slight incremental update to my patch from yesterday. It also 
adds the config variable, and it defaults to off, so to actually see this 
in action, you now need to add

	[core]
		PreloadIndex = true

to your ~/.gitconfig file.

Totally untested. As usual. Maybe it works. Maybe it doesn't.

		Linus

---
 Documentation/config.txt |   12 +++++++++++-
 cache.h                  |    1 +
 config.c                 |    5 +++++
 environment.c            |    3 +++
 preload-index.c          |   18 +++++++++++++-----
 5 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 32dcd64..9260121 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -411,7 +411,17 @@ core.fsyncobjectfiles::
 This is a total waste of time and effort on a filesystem that orders
 data writes properly, but can be useful for filesystems that do not use
 journalling (traditional UNIX filesystems) or that only journal metadata
-and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback").
+and not file contents (OS X's HFS+, or Linux ext3 with
+"data=writeback").
+
+core.preloadindex::
+	Enable parallel index preload for operations like 'git diff'
++
+This can speed up operations like 'git diff' and 'git status' especially
+on filesystems like NFS that have weak caching semantics and thus
+relatively high IO latencies.  With this set to 'true', git will do the
+index comparison to the filesystem data in parallel, allowing
+overlapping IO's.
 
 alias.*::
 	Command aliases for the linkgit:git[1] command wrapper - e.g.
diff --git a/cache.h b/cache.h
index 64239fb..685a866 100644
--- a/cache.h
+++ b/cache.h
@@ -460,6 +460,7 @@ extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern int auto_crlf;
 extern int fsync_object_files;
+extern int core_preload_index;
 
 enum safe_crlf {
 	SAFE_CRLF_FALSE = 0,
diff --git a/config.c b/config.c
index 67cc1dc..d2fc8f5 100644
--- a/config.c
+++ b/config.c
@@ -490,6 +490,11 @@ static int git_default_core_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.preloadindex")) {
+		core_preload_index = git_config_bool(var, value);
+		return 0;
+	}
+
 	/* Add other config variables here and to Documentation/config.txt. */
 	return 0;
 }
diff --git a/environment.c b/environment.c
index bb96ac0..e278bce 100644
--- a/environment.c
+++ b/environment.c
@@ -43,6 +43,9 @@ unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
 enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
 
+/* Parallel index stat data preload? */
+int core_preload_index = 0;
+
 /* This is set by setup_git_dir_gently() and/or git_default_config() */
 char *git_work_tree_cfg;
 static char *work_tree;
diff --git a/preload-index.c b/preload-index.c
index e322c27..3ce42e0 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -4,9 +4,14 @@
 #include <pthread.h>
 #include "cache.h"
 
-/* Hacky hack-hack start */
-#define MAX_PARALLEL (100)
-int parallel_lstats = 1;
+/*
+ * Mostly randomly chosen maximum thread counts: we
+ * cap the parallelism to 20 threads, and we want
+ * to have at least 500 lstat's per thread for it to
+ * be worth starting a thread.
+ */
+#define MAX_PARALLEL (20)
+#define THREAD_COST (500)
 
 struct thread_data {
 	pthread_t pthread;
@@ -47,10 +52,13 @@ static void *preload_thread(void *_data)
 
 static void preload_index(struct index_state *index, const char **pathspec)
 {
-	int i, work, offset;
-	int threads = index->cache_nr / 100;
+	int threads, i, work, offset;
 	struct thread_data data[MAX_PARALLEL];
 
+	if (!core_preload_index)
+		return;
+
+	threads = index->cache_nr / THREAD_COST;
 	if (threads < 2)
 		return;
 	if (threads > MAX_PARALLEL)

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

* Re: hosting git on a nfs
  2008-11-14 19:23                     ` Linus Torvalds
@ 2008-11-14 20:14                       ` Junio C Hamano
  2008-11-14 23:10                         ` Linus Torvalds
  2008-11-15 12:08                       ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
  1 sibling, 1 reply; 44+ messages in thread
From: Junio C Hamano @ 2008-11-14 20:14 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Brandon Casey, James Pickens, Bruce Fields, Git Mailing List

Linus Torvalds <torvalds@linux-foundation.org> writes:

> I also think the thread cost was wrong: it did
>
> 	threads = index->cache_nr / 100;
>
> to give a first-order "how many threads do we want", but the thread 
> startup is likely to be higher than 100 lstat calls, so we probably want 
> fewer threads than that. It doesn't much matter for something like the 
> Linux kernel, where there are so many files that we'll end up maxing out 
> the threads anyway, but for smaller projects, I suspect a thread cost of 
> "one thread per 500 files" is more reasonable. You almost certainly don't 
> want to thread anything at all for fewer than a few hundred files.

If you have 1000 files in a single directory, do you still want 2 threads
following the "1/500" rule, or they would compete reading the same
directory and using a single thread is better off?

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

* Re: hosting git on a nfs
  2008-11-14 20:14                       ` Junio C Hamano
@ 2008-11-14 23:10                         ` Linus Torvalds
  0 siblings, 0 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-14 23:10 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Brandon Casey, James Pickens, Bruce Fields, Git Mailing List



On Fri, 14 Nov 2008, Junio C Hamano wrote:
> 
> If you have 1000 files in a single directory, do you still want 2 threads
> following the "1/500" rule, or they would compete reading the same
> directory and using a single thread is better off?

Well, first off, the "single directory" thing is really a Linux kernel 
deficiency, and it's entirely possible that it doesn't even exist on other 
systems. Linux has a very special directory cache (dcache) model that is 
pretty unique - it's part of why cached 'lstat()' calls are so cheap on 
Linux - but it is also part of the reason for why we serialize lookups 
when we do miss in the cache (*).

Secondly, anybody who has a thousand tracked files in a single directory 
can damn well blame themselves for being stupid. So I don't think it's a 
case that is worth worrying too much about. Git will slow down for that 
kind of situation for other reasons (ie a lot of the tree pruning 
optimization won't work for projects that have large flat directories).

So i wouldn't worry about it. That said, with the second patch, we default 
to having people enable this explicitly, so it's something that people can 
decide on their own.

			Linus

(*) That said - the Linux dcache consistency is just _one_ reason why we 
serialize lookups. I would not be in the least surprised if other OS's 
have the exact same issue. I'd love to fix it in Linux, but quiet 
honestly, it has never actually come up before now, and we've literally 
worked on multi-threading the _cached_ case, not the uncached one.

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

* [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-14 19:23                     ` Linus Torvalds
  2008-11-14 20:14                       ` Junio C Hamano
@ 2008-11-15 12:08                       ` Junio C Hamano
  2008-11-15 17:15                         ` Linus Torvalds
  1 sibling, 1 reply; 44+ messages in thread
From: Junio C Hamano @ 2008-11-15 12:08 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Linus Torvalds

This introduces make variable NO_PTHREADS for platforms that lack the
support for pthreads library or people who do not want to use it for
whatever reason.  When defined, it makes the multi-threaded index
preloading into a no-op, and also disables threaded delta searching by
pack-objects.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * I notice a handful platforms do not define THREADED_DELTA_SEARCH, and
   on them Linus's preload-index.c is the first source file that includes
   <pthreads.h>, which may result in breakages.

 Makefile        |   10 +++++++++-
 config.mak.in   |    1 +
 configure.ac    |    5 +++++
 preload-index.c |    9 +++++++++
 4 files changed, 24 insertions(+), 1 deletions(-)

diff --git c/Makefile w/Makefile
index acac0ae..ffc9531 100644
--- c/Makefile
+++ w/Makefile
@@ -90,6 +90,8 @@ all::
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define NO_PTHREADS if you do not have or do not want to use Pthreads.
+#
 # Define NO_PREAD if you have a problem with pread() system call (e.g.
 # cygwin.dll before v1.5.22).
 #
@@ -1018,9 +1020,15 @@ ifdef INTERNAL_QSORT
 	COMPAT_OBJS += compat/qsort.o
 endif
 
+ifdef NO_PTHREADS
+	THREADED_DELTA_SEARCH =
+	BASIC_CFLAGS += -DNO_PTHREADS
+else
+	EXTLIBS += $(PTHREAD_LIBS)
+endif
+
 ifdef THREADED_DELTA_SEARCH
 	BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH
-	EXTLIBS += $(PTHREAD_LIBS)
 	LIB_OBJS += thread-utils.o
 endif
 ifdef DIR_HAS_BSD_GROUP_SEMANTICS
diff --git c/config.mak.in w/config.mak.in
index ea7705c..14dfb21 100644
--- c/config.mak.in
+++ w/config.mak.in
@@ -51,4 +51,5 @@ OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
 FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@
 SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
+NO_PTHREADS=@NO_PTHREADS@
 PTHREAD_LIBS=@PTHREAD_LIBS@
diff --git c/configure.ac w/configure.ac
index 4256742..8821b50 100644
--- c/configure.ac
+++ w/configure.ac
@@ -490,6 +490,8 @@ AC_SUBST(NO_MKDTEMP)
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
+# Define NO_PTHREADS if we do not have pthreads
+#
 # Define PTHREAD_LIBS to the linker flag used for Pthread support.
 AC_LANG_CONFTEST([AC_LANG_PROGRAM(
   [[#include <pthread.h>]],
@@ -502,9 +504,12 @@ else
  ${CC} -lpthread conftest.c -o conftest.o > /dev/null 2>&1
  if test $? -eq 0;then
   PTHREAD_LIBS="-lpthread"
+ else
+  NO_PTHREADS=UnfortunatelyYes
  fi
 fi
 AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(NO_PTHREADS)
 
 ## Site configuration (override autodetection)
 ## --with-PACKAGE[=ARG] and --without-PACKAGE
diff --git c/preload-index.c w/preload-index.c
index 6253578..3ae83dc 100644
--- c/preload-index.c
+++ w/preload-index.c
@@ -2,6 +2,14 @@
  * Copyright (C) 2008 Linus Torvalds
  */
 #include "cache.h"
+
+#ifdef NO_PTHREADS
+static void preload_index(struct index_state *index, const char **pathspec)
+{
+	; /* nothing */
+}
+#else
+
 #include <pthread.h>
 
 /*
@@ -81,6 +89,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
 			die("unable to join threaded lstat");
 	}
 }
+#endif
 
 int read_index_preload(struct index_state *index, const char **pathspec)
 {

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-15 12:08                       ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
@ 2008-11-15 17:15                         ` Linus Torvalds
  2008-11-17 10:03                           ` Mike Ralphson
                                             ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-15 17:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List



On Sat, 15 Nov 2008, Junio C Hamano wrote:
>
> This introduces make variable NO_PTHREADS for platforms that lack the
> support for pthreads library or people who do not want to use it for
> whatever reason.  When defined, it makes the multi-threaded index
> preloading into a no-op, and also disables threaded delta searching by
> pack-objects.

Ack. Makes sense.

		Linus

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-15 17:15                         ` Linus Torvalds
@ 2008-11-17 10:03                           ` Mike Ralphson
  2008-11-17 10:18                             ` Junio C Hamano
  2008-11-17 10:34                             ` Johannes Sixt
  2008-11-17 16:38                           ` Junio C Hamano
  2008-11-17 16:41                           ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
  2 siblings, 2 replies; 44+ messages in thread
From: Mike Ralphson @ 2008-11-17 10:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Sixt, Git Mailing List, Linus Torvalds

2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>
> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>
>> This introduces make variable NO_PTHREADS for platforms that lack the
>> support for pthreads library or people who do not want to use it for
>> whatever reason.  When defined, it makes the multi-threaded index
>> preloading into a no-op, and also disables threaded delta searching by
>> pack-objects.
>
> Ack. Makes sense.

I'd be minded to make this the default on AIX to keep the prerequisite
list as small as possible, then people can opt-in for the performance
benefits if required.

I'll wait a little while to see if anyone else reports the same for
other platforms and then submit a patch.

Mike

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 10:03                           ` Mike Ralphson
@ 2008-11-17 10:18                             ` Junio C Hamano
  2008-11-17 10:34                             ` Johannes Sixt
  1 sibling, 0 replies; 44+ messages in thread
From: Junio C Hamano @ 2008-11-17 10:18 UTC (permalink / raw)
  To: Mike Ralphson; +Cc: Johannes Sixt, Git Mailing List, Linus Torvalds

"Mike Ralphson" <mike.ralphson@gmail.com> writes:

> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>>
>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>>
>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>> support for pthreads library or people who do not want to use it for
>>> whatever reason.  When defined, it makes the multi-threaded index
>>> preloading into a no-op, and also disables threaded delta searching by
>>> pack-objects.
>>
>> Ack. Makes sense.
>
> I'd be minded to make this the default on AIX to keep the prerequisite
> list as small as possible, then people can opt-in for the performance
> benefits if required.
>
> I'll wait a little while to see if anyone else reports the same for
> other platforms and then submit a patch.

Thanks.

I expect to be slow this week til just before Thanksgiving, so the more
people we have to keep an eye on the areas they excel at, the better for
all of us and certainly it would help me a lot.

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 10:03                           ` Mike Ralphson
  2008-11-17 10:18                             ` Junio C Hamano
@ 2008-11-17 10:34                             ` Johannes Sixt
  2008-11-17 10:45                               ` Mike Ralphson
  1 sibling, 1 reply; 44+ messages in thread
From: Johannes Sixt @ 2008-11-17 10:34 UTC (permalink / raw)
  To: Mike Ralphson; +Cc: Junio C Hamano, Git Mailing List, Linus Torvalds

Mike Ralphson schrieb:
> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>> support for pthreads library or people who do not want to use it for
>>> whatever reason.  When defined, it makes the multi-threaded index
>>> preloading into a no-op, and also disables threaded delta searching by
>>> pack-objects.
>> Ack. Makes sense.
> 
> I'd be minded to make this the default on AIX to keep the prerequisite
> list as small as possible, then people can opt-in for the performance
> benefits if required.

Is pthreads not a standard shipment on AIX? I would set NO_PTHREADS only
if we know in advance that there are many installations without pthreads.
(And I don't know what the situation is.)

BTW, this needs to be squashed in, because we don't have pthreads on Windows:

diff --git a/Makefile b/Makefile
index ffc9531..3a30b8c 100644
--- a/Makefile
+++ b/Makefile
@@ -769,6 +769,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_STRCASESTR = YesPlease
 	NO_STRLCPY = YesPlease
 	NO_MEMMEM = YesPlease
+	NO_PTHREADS = YesPlease
 	NEEDS_LIBICONV = YesPlease
 	OLD_ICONV = YesPlease
 	NO_C99_FORMAT = YesPlease

-- Hannes

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 10:34                             ` Johannes Sixt
@ 2008-11-17 10:45                               ` Mike Ralphson
  2008-11-17 11:25                                 ` Johannes Sixt
  0 siblings, 1 reply; 44+ messages in thread
From: Mike Ralphson @ 2008-11-17 10:45 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, Git Mailing List, Linus Torvalds

2008/11/17 Johannes Sixt <j.sixt@viscovery.net>:
> Mike Ralphson schrieb:
>> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>>> support for pthreads library or people who do not want to use it for
>>>> whatever reason.  When defined, it makes the multi-threaded index
>>>> preloading into a no-op, and also disables threaded delta searching by
>>>> pack-objects.
>>> Ack. Makes sense.
>>
>> I'd be minded to make this the default on AIX to keep the prerequisite
>> list as small as possible, then people can opt-in for the performance
>> benefits if required.
>
> Is pthreads not a standard shipment on AIX? I would set NO_PTHREADS only
> if we know in advance that there are many installations without pthreads.
> (And I don't know what the situation is.)

I should have dug a bit further, it seems to be present on my 5.3
machines but I still need to determine whether it got installed by
default. Either way it must need some other link flags...

> BTW, this needs to be squashed in, because we don't have pthreads on Windows:
>
> diff --git a/Makefile b/Makefile
> index ffc9531..3a30b8c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -769,6 +769,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
>        NO_STRCASESTR = YesPlease
>        NO_STRLCPY = YesPlease
>        NO_MEMMEM = YesPlease
> +       NO_PTHREADS = YesPlease
>        NEEDS_LIBICONV = YesPlease
>        OLD_ICONV = YesPlease
>        NO_C99_FORMAT = YesPlease
>

Ta. Ok to add your S-o-B on a squashed patch?

Mike

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 10:45                               ` Mike Ralphson
@ 2008-11-17 11:25                                 ` Johannes Sixt
  2008-12-01  8:29                                   ` Johannes Sixt
  0 siblings, 1 reply; 44+ messages in thread
From: Johannes Sixt @ 2008-11-17 11:25 UTC (permalink / raw)
  To: Mike Ralphson; +Cc: Junio C Hamano, Git Mailing List, Linus Torvalds

Mike Ralphson schrieb:
> 2008/11/17 Johannes Sixt <j.sixt@viscovery.net>:
>> Mike Ralphson schrieb:
>>> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>>>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>>>> support for pthreads library or people who do not want to use it for
>>>>> whatever reason.  When defined, it makes the multi-threaded index
>>>>> preloading into a no-op, and also disables threaded delta searching by
>>>>> pack-objects.
>>>> Ack. Makes sense.
>>> I'd be minded to make this the default on AIX to keep the prerequisite
>>> list as small as possible, then people can opt-in for the performance
>>> benefits if required.
>> Is pthreads not a standard shipment on AIX? I would set NO_PTHREADS only
>> if we know in advance that there are many installations without pthreads.
>> (And I don't know what the situation is.)
> 
> I should have dug a bit further, it seems to be present on my 5.3
> machines but I still need to determine whether it got installed by
> default. Either way it must need some other link flags...

I tried compiling with THREADED_DELTA_SEARCH=Yes, and it fails with

    CC builtin-pack-objects.o
In file included from /usr/include/sys/pri.h:29,
                 from /usr/include/sys/sched.h:38,
                 from /usr/include/sched.h:52,
                 from /usr/include/pthread.h:43,
                 from builtin-pack-objects.c:22:
/usr/include/sys/proc.h:203: parse error before "crid_t"
/usr/include/sys/proc.h:212: parse error before "p_class"
/usr/include/sys/proc.h:355: parse error before '}' token

:-( Maybe NO_PTHREADS is indeed the safer choice? I'm not going to dig
into this today, though. (I'm on AIX 4.3.something.)

>> BTW, this needs to be squashed in, because we don't have pthreads on Windows:
>>
>> diff --git a/Makefile b/Makefile
>> index ffc9531..3a30b8c 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -769,6 +769,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
>>        NO_STRCASESTR = YesPlease
>>        NO_STRLCPY = YesPlease
>>        NO_MEMMEM = YesPlease
>> +       NO_PTHREADS = YesPlease
>>        NEEDS_LIBICONV = YesPlease
>>        OLD_ICONV = YesPlease
>>        NO_C99_FORMAT = YesPlease
>>
> 
> Ta. Ok to add your S-o-B on a squashed patch?

Sure. Use this address please:

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

-- Hannes

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-15 17:15                         ` Linus Torvalds
  2008-11-17 10:03                           ` Mike Ralphson
@ 2008-11-17 16:38                           ` Junio C Hamano
  2008-11-17 16:47                             ` Linus Torvalds
  2008-11-17 16:41                           ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
  2 siblings, 1 reply; 44+ messages in thread
From: Junio C Hamano @ 2008-11-17 16:38 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

Linus Torvalds <torvalds@linux-foundation.org> writes:

> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>
>> This introduces make variable NO_PTHREADS for platforms that lack the
>> support for pthreads library or people who do not want to use it for
>> whatever reason.  When defined, it makes the multi-threaded index
>> preloading into a no-op, and also disables threaded delta searching by
>> pack-objects.
>
> Ack. Makes sense.

Hmm, I started getting random segfaults that sometimes reproduces.  For
example, this is what I just got from "git diff --stat $some_commit".

#0  0x00002b952568b090 in strlen () from /lib/libc.so.6
#1  0x000000000044ed42 in git_checkattr (path=0x2b95284b3970 "parse-options.c",
    num=3, check=0x41000e90) at attr.c:512
#2  0x0000000000458921 in convert_to_git (
    path=0x2b95284b3970 "parse-options.c",
    src=0x2aaaaaabb000 <Address 0x2aaaaaabb000 out of bounds>, len=12594,
    dst=0x41000f30, checksafe=SAFE_CRLF_FALSE) at convert.c:578
#3  0x0000000000489ac3 in index_mem (
    sha1=0x41000ff0 "\210f�⽡x�\207�� 7R}\217\032��", buf=0x2aaaaaabb000,
    size=12594, write_object=0, type=<value optimized out>,
    path=0x2f2f2f2f2f2f2f2f <Address 0x2f2f2f2f2f2f2f2f out of bounds>)
    at sha1_file.c:2451
#4  0x0000000000489c3d in index_fd (
    sha1=0x41000ff0 "\210f�⽡x�\207�� 7R}\217\032��", fd=5,
    st=<value optimized out>, write_object=0, type=OBJ_BLOB,
    path=0x2b95284b3970 "parse-options.c") at sha1_file.c:2483
#5  0x000000000047857a in ce_modified_check_fs (ce=0x2b95284b3930,
    st=0x41001080) at read-cache.c:92
#6  0x00000000004786a2 in ie_match_stat (istate=0x71c860, ce=0x2b95284b3930,
    st=0x41001080, options=<value optimized out>) at read-cache.c:282
#7  0x0000000000497e65 in preload_thread (_data=<value optimized out>)
    at preload-index.c:46
#8  0x00002b9525964017 in start_thread () from /lib/libpthread.so.0
#9  0x00002b95256da5bd in clone () from /lib/libc.so.6
#10 0x0000000000000000 in ?? ()

I suspect that the callpath around ce_modified_check_fs() uses a buffer
obtained from path.c:get_pathname() and parallel threads stomp on each
other, but I do not have time to debug this right now (I will be on a
14-hour flight in a few hours).

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-15 17:15                         ` Linus Torvalds
  2008-11-17 10:03                           ` Mike Ralphson
  2008-11-17 16:38                           ` Junio C Hamano
@ 2008-11-17 16:41                           ` Junio C Hamano
  2 siblings, 0 replies; 44+ messages in thread
From: Junio C Hamano @ 2008-11-17 16:41 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

Linus Torvalds <torvalds@linux-foundation.org> writes:

> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>
>> This introduces make variable NO_PTHREADS for platforms that lack the
>> support for pthreads library or people who do not want to use it for
>> whatever reason.  When defined, it makes the multi-threaded index
>> preloading into a no-op, and also disables threaded delta searching by
>> pack-objects.
>
> Ack. Makes sense.

Hmm, I started getting random segfaults that sometimes reproduce.  For
example, this is what I just got from "git diff --stat $some_commit".

#0  0x00002b952568b090 in strlen () from /lib/libc.so.6
#1  0x000000000044ed42 in git_checkattr (path=0x2b95284b3970 "parse-options.c",
    num=3, check=0x41000e90) at attr.c:512
#2  0x0000000000458921 in convert_to_git (
    path=0x2b95284b3970 "parse-options.c",
    src=0x2aaaaaabb000 <Address 0x2aaaaaabb000 out of bounds>, len=12594,
    dst=0x41000f30, checksafe=SAFE_CRLF_FALSE) at convert.c:578
#3  0x0000000000489ac3 in index_mem (
    sha1=0x41000ff0 "\210f�⽡x�\207�� 7R}\217\032��", buf=0x2aaaaaabb000,
    size=12594, write_object=0, type=<value optimized out>,
    path=0x2f2f2f2f2f2f2f2f <Address 0x2f2f2f2f2f2f2f2f out of bounds>)
    at sha1_file.c:2451
#4  0x0000000000489c3d in index_fd (
    sha1=0x41000ff0 "\210f�⽡x�\207�� 7R}\217\032��", fd=5,
    st=<value optimized out>, write_object=0, type=OBJ_BLOB,
    path=0x2b95284b3970 "parse-options.c") at sha1_file.c:2483
#5  0x000000000047857a in ce_modified_check_fs (ce=0x2b95284b3930,
    st=0x41001080) at read-cache.c:92
#6  0x00000000004786a2 in ie_match_stat (istate=0x71c860, ce=0x2b95284b3930,
    st=0x41001080, options=<value optimized out>) at read-cache.c:282
#7  0x0000000000497e65 in preload_thread (_data=<value optimized out>)
    at preload-index.c:46
#8  0x00002b9525964017 in start_thread () from /lib/libpthread.so.0
#9  0x00002b95256da5bd in clone () from /lib/libc.so.6
#10 0x0000000000000000 in ?? ()

Unfortunately, I do not have time to debug this right now (I will be on a
14-hour flight in a few hours).

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 16:38                           ` Junio C Hamano
@ 2008-11-17 16:47                             ` Linus Torvalds
  2008-11-17 17:01                               ` Fix index preloading for racy dirty case Linus Torvalds
  0 siblings, 1 reply; 44+ messages in thread
From: Linus Torvalds @ 2008-11-17 16:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List



On Mon, 17 Nov 2008, Junio C Hamano wrote:
> 
> I suspect that the callpath around ce_modified_check_fs() uses a buffer
> obtained from path.c:get_pathname() and parallel threads stomp on each
> other, but I do not have time to debug this right now (I will be on a
> 14-hour flight in a few hours).

Oh, damn. I had forgotten that check_fs() doesn't just do a "lstat()" any 
more. You're right.

Let me look at it. 

		Linus

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

* Fix index preloading for racy dirty case
  2008-11-17 16:47                             ` Linus Torvalds
@ 2008-11-17 17:01                               ` Linus Torvalds
  0 siblings, 0 replies; 44+ messages in thread
From: Linus Torvalds @ 2008-11-17 17:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List



In the threaded index preloading case, we must be sure to always use the 
CE_MATCH_RACY_IS_DIRTY flag when calling ie_match_stat(), in order to make 
sure that we only ever look at the stat() data, and don't try to do 
anything fancy.

Because most of git internals are not thread-safe, and must not be called 
in parallel.

Otherwise, what happens is that if the timestamps indicate that an entry 
_might_ be dirty, we might start actually comparing filesystem data with 
the object database. And we mustn't do that, because that would involve
looking up and creating the object structure, and that whole code sequence 
with read_sha1_file() where we look up and add objects to the hashes is 
definitely not thread-safe.

Nor do we want to add locking, because the whole point of the preload was 
to be simple and not affect anything else. With CE_MATCH_RACY_IS_DIRTY, we 
get what we wanted, and we'll just leave the hard cases well alone, to be 
done later in the much simpler serial case.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---

On Mon, 17 Nov 2008, Linus Torvalds wrote:
> 
> Oh, damn. I had forgotten that check_fs() doesn't just do a "lstat()" any 
> more. You're right.

Never mind the "any more". I don't think it ever did.

But I do think that this is trivially fixed, and I should have thought 
about it. And while I didn't reproduce your SIGSEGV, I think this trivial 
patch should fix it.

Sorry about the mindfart.

 preload-index.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/preload-index.c b/preload-index.c
index 3ce42e0..a6a6bdb 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -43,7 +43,7 @@ static void *preload_thread(void *_data)
 			continue;
 		if (lstat(ce->name, &st))
 			continue;
-		if (ie_match_stat(index, ce, &st, 0))
+		if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY))
 			continue;
 		ce_mark_uptodate(ce);
 	} while (--nr > 0);

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-11-17 11:25                                 ` Johannes Sixt
@ 2008-12-01  8:29                                   ` Johannes Sixt
  2008-12-01  8:48                                     ` dhruva
                                                       ` (3 more replies)
  0 siblings, 4 replies; 44+ messages in thread
From: Johannes Sixt @ 2008-12-01  8:29 UTC (permalink / raw)
  To: Mike Ralphson; +Cc: Junio C Hamano, Git Mailing List, Linus Torvalds

Johannes Sixt schrieb:
> Mike Ralphson schrieb:
>> 2008/11/17 Johannes Sixt <j.sixt@viscovery.net>:
>>> Mike Ralphson schrieb:
>>>> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>>>>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>>>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>>>>> support for pthreads library or people who do not want to use it for
>>>>>> whatever reason.  When defined, it makes the multi-threaded index
>>>>>> preloading into a no-op, and also disables threaded delta searching by
>>>>>> pack-objects.
>>>>> Ack. Makes sense.
>>>> I'd be minded to make this the default on AIX to keep the prerequisite
>>>> list as small as possible, then people can opt-in for the performance
>>>> benefits if required.
>>> Is pthreads not a standard shipment on AIX? I would set NO_PTHREADS only
>>> if we know in advance that there are many installations without pthreads.
>>> (And I don't know what the situation is.)
>> I should have dug a bit further, it seems to be present on my 5.3
>> machines but I still need to determine whether it got installed by
>> default. Either way it must need some other link flags...
> 
> I tried compiling with THREADED_DELTA_SEARCH=Yes, and it fails with
> 
>     CC builtin-pack-objects.o
> In file included from /usr/include/sys/pri.h:29,
>                  from /usr/include/sys/sched.h:38,
>                  from /usr/include/sched.h:52,
>                  from /usr/include/pthread.h:43,
>                  from builtin-pack-objects.c:22:
> /usr/include/sys/proc.h:203: parse error before "crid_t"
> /usr/include/sys/proc.h:212: parse error before "p_class"
> /usr/include/sys/proc.h:355: parse error before '}' token
> 
> :-( Maybe NO_PTHREADS is indeed the safer choice? I'm not going to dig
> into this today, though. (I'm on AIX 4.3.something.)
> 
>>> BTW, this needs to be squashed in, because we don't have pthreads on Windows:
>>>
>>> diff --git a/Makefile b/Makefile
>>> index ffc9531..3a30b8c 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -769,6 +769,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
>>>        NO_STRCASESTR = YesPlease
>>>        NO_STRLCPY = YesPlease
>>>        NO_MEMMEM = YesPlease
>>> +       NO_PTHREADS = YesPlease
>>>        NEEDS_LIBICONV = YesPlease
>>>        OLD_ICONV = YesPlease
>>>        NO_C99_FORMAT = YesPlease
>>>
>> Ta. Ok to add your S-o-B on a squashed patch?
> 
> Sure. Use this address please:
> 
> Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Mike,

you said you would resend the patch, but I think you forgot about it.
Would you do that now, please?

-- Hannes

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-01  8:29                                   ` Johannes Sixt
@ 2008-12-01  8:48                                     ` dhruva
  2008-12-01  9:57                                     ` Mike Ralphson
                                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 44+ messages in thread
From: dhruva @ 2008-12-01  8:48 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Mike Ralphson, Junio C Hamano, Git Mailing List, Linus Torvalds

Hello,
 I am able to compile and use git by defining THREADED_DELTA_SEARCH
and copying setjmp.h from mingw (www.mingw.org) to msys include folder
with small changes to it. If it does add value, we should try to
enable this by default.

-dhruva

On Mon, Dec 1, 2008 at 1:59 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:
> Johannes Sixt schrieb:
>> Mike Ralphson schrieb:
>>> 2008/11/17 Johannes Sixt <j.sixt@viscovery.net>:
>>>> Mike Ralphson schrieb:
>>>>> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
>>>>>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
>>>>>>> This introduces make variable NO_PTHREADS for platforms that lack the
>>>>>>> support for pthreads library or people who do not want to use it for
>>>>>>> whatever reason.  When defined, it makes the multi-threaded index
>>>>>>> preloading into a no-op, and also disables threaded delta searching by
>>>>>>> pack-objects.
>>>>>> Ack. Makes sense.
>>>>> I'd be minded to make this the default on AIX to keep the prerequisite
>>>>> list as small as possible, then people can opt-in for the performance
>>>>> benefits if required.
>>>> Is pthreads not a standard shipment on AIX? I would set NO_PTHREADS only
>>>> if we know in advance that there are many installations without pthreads.
>>>> (And I don't know what the situation is.)
>>> I should have dug a bit further, it seems to be present on my 5.3
>>> machines but I still need to determine whether it got installed by
>>> default. Either way it must need some other link flags...
>>
>> I tried compiling with THREADED_DELTA_SEARCH=Yes, and it fails with
>>
>>     CC builtin-pack-objects.o
>> In file included from /usr/include/sys/pri.h:29,
>>                  from /usr/include/sys/sched.h:38,
>>                  from /usr/include/sched.h:52,
>>                  from /usr/include/pthread.h:43,
>>                  from builtin-pack-objects.c:22:
>> /usr/include/sys/proc.h:203: parse error before "crid_t"
>> /usr/include/sys/proc.h:212: parse error before "p_class"
>> /usr/include/sys/proc.h:355: parse error before '}' token
>>
>> :-( Maybe NO_PTHREADS is indeed the safer choice? I'm not going to dig
>> into this today, though. (I'm on AIX 4.3.something.)
>>
>>>> BTW, this needs to be squashed in, because we don't have pthreads on Windows:
>>>>
>>>> diff --git a/Makefile b/Makefile
>>>> index ffc9531..3a30b8c 100644
>>>> --- a/Makefile
>>>> +++ b/Makefile
>>>> @@ -769,6 +769,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
>>>>        NO_STRCASESTR = YesPlease
>>>>        NO_STRLCPY = YesPlease
>>>>        NO_MEMMEM = YesPlease
>>>> +       NO_PTHREADS = YesPlease
>>>>        NEEDS_LIBICONV = YesPlease
>>>>        OLD_ICONV = YesPlease
>>>>        NO_C99_FORMAT = YesPlease
>>>>
>>> Ta. Ok to add your S-o-B on a squashed patch?
>>
>> Sure. Use this address please:
>>
>> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
>
> Mike,
>
> you said you would resend the patch, but I think you forgot about it.
> Would you do that now, please?
>
> -- Hannes
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Contents reflect my personal views only!

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-01  8:29                                   ` Johannes Sixt
  2008-12-01  8:48                                     ` dhruva
@ 2008-12-01  9:57                                     ` Mike Ralphson
  2008-12-01 16:09                                     ` Mike Ralphson
  2008-12-01 16:13                                     ` Mike Ralphson
  3 siblings, 0 replies; 44+ messages in thread
From: Mike Ralphson @ 2008-12-01  9:57 UTC (permalink / raw)
  To: Johannes Sixt, Junio C Hamano; +Cc: Git Mailing List, Linus Torvalds, dhruvakm

2008/12/1 Johannes Sixt <j.sixt@viscovery.net>
>
> Johannes Sixt schrieb:
> > Mike Ralphson schrieb:
> >> 2008/11/17 Johannes Sixt <j.sixt@viscovery.net>:
> >>> Mike Ralphson schrieb:
> >>>> 2008/11/15 Linus Torvalds <torvalds@linux-foundation.org>:
> >>>>> On Sat, 15 Nov 2008, Junio C Hamano wrote:
> >>>>>> This introduces make variable NO_PTHREADS for platforms that lack the
> >>>>>> support for pthreads library or people who do not want to use it for
> >>>>>> whatever reason.  When defined, it makes the multi-threaded index
> >>>>>> preloading into a no-op, and also disables threaded delta searching by
> >>>>>> pack-objects.
> >>>>> ...
> >
> > :-( Maybe NO_PTHREADS is indeed the safer choice? I'm not going to dig
> > into this today, though. (I'm on AIX 4.3.something.)
> >
> >>> BTW, this needs to be squashed in, because we don't have pthreads on Windows:
> >>>...
>
> you said you would resend the patch, but I think you forgot about it.
> Would you do that now, please?

Not forgotten, just slow. The current state I believe is we should
have NO_PTHREADS for AIX < v5. THREADED_DELTA_SEARCH and the new
multi-threaded lstat are actually ok on AIX 5.3 at least - though I
couldn't see any performance benefit on my repo / hardware
combination.

But now after dhruva's observation I'm unsure what the desired change
is for Windows. 8-(

Mike

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

* [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-01  8:29                                   ` Johannes Sixt
  2008-12-01  8:48                                     ` dhruva
  2008-12-01  9:57                                     ` Mike Ralphson
@ 2008-12-01 16:09                                     ` Mike Ralphson
  2008-12-01 16:13                                     ` Mike Ralphson
  3 siblings, 0 replies; 44+ messages in thread
From: Mike Ralphson @ 2008-12-01 16:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Mike Ralphson, j.sixt

From: Junio C Hamano <gitster@pobox.com>

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Mike Ralphson <mike@abacus.co.uk>
---

* I notice a handful platforms do not define THREADED_DELTA_SEARCH, and
 on them Linus's preload-index.c is the first source file that includes
 <pthreads.h>, which may result in breakages.

 Made the default for AIX <5 and Mingw

 Author should still show as Junio, apologies if not

 Makefile        |   17 ++++++++++++++++-
 config.mak.in   |    1 +
 configure.ac    |    5 +++++
 preload-index.c |    9 +++++++++
 4 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index d1e2116..5a69a41 100644
--- a/Makefile
+++ b/Makefile
@@ -90,6 +90,8 @@ all::
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define NO_PTHREADS if you do not have or do not want to use Pthreads.
+#
 # Define NO_PREAD if you have a problem with pread() system call (e.g.
 # cygwin.dll before v1.5.22).
 #
@@ -164,6 +166,7 @@ uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
 uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
 uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
 uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
+uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
 
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
@@ -722,6 +725,11 @@ ifeq ($(uname_S),AIX)
 	INTERNAL_QSORT = UnfortunatelyYes
 	NEEDS_LIBICONV=YesPlease
 	BASIC_CFLAGS += -D_LARGE_FILES
+	ifneq ($(shell expr "$(uname_V)" : '[1234]'),1)
+		THREADED_DELTA_SEARCH = YesPlease
+	else
+		NO_PTHREADS = YesPlease
+	endif
 endif
 ifeq ($(uname_S),GNU)
 	# GNU/Hurd
@@ -766,6 +774,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_STRCASESTR = YesPlease
 	NO_STRLCPY = YesPlease
 	NO_MEMMEM = YesPlease
+	NO_PTHREADS = YesPlease
 	NEEDS_LIBICONV = YesPlease
 	OLD_ICONV = YesPlease
 	NO_C99_FORMAT = YesPlease
@@ -1017,9 +1026,15 @@ ifdef INTERNAL_QSORT
 	COMPAT_OBJS += compat/qsort.o
 endif
 
+ifdef NO_PTHREADS
+	THREADED_DELTA_SEARCH =
+	BASIC_CFLAGS += -DNO_PTHREADS
+else
+	EXTLIBS += $(PTHREAD_LIBS)
+endif
+
 ifdef THREADED_DELTA_SEARCH
 	BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH
-	EXTLIBS += $(PTHREAD_LIBS)
 	LIB_OBJS += thread-utils.o
 endif
 ifdef DIR_HAS_BSD_GROUP_SEMANTICS
diff --git a/config.mak.in b/config.mak.in
index ea7705c..14dfb21 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -51,4 +51,5 @@ OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
 FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@
 SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
+NO_PTHREADS=@NO_PTHREADS@
 PTHREAD_LIBS=@PTHREAD_LIBS@
diff --git a/configure.ac b/configure.ac
index 4256742..8821b50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -490,6 +490,8 @@ AC_SUBST(NO_MKDTEMP)
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
+# Define NO_PTHREADS if we do not have pthreads
+#
 # Define PTHREAD_LIBS to the linker flag used for Pthread support.
 AC_LANG_CONFTEST([AC_LANG_PROGRAM(
   [[#include <pthread.h>]],
@@ -502,9 +504,12 @@ else
  ${CC} -lpthread conftest.c -o conftest.o > /dev/null 2>&1
  if test $? -eq 0;then
   PTHREAD_LIBS="-lpthread"
+ else
+  NO_PTHREADS=UnfortunatelyYes
  fi
 fi
 AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(NO_PTHREADS)
 
 ## Site configuration (override autodetection)
 ## --with-PACKAGE[=ARG] and --without-PACKAGE
diff --git a/preload-index.c b/preload-index.c
index a685583..88edc5f 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -2,6 +2,14 @@
  * Copyright (C) 2008 Linus Torvalds
  */
 #include "cache.h"
+
+#ifdef NO_PTHREADS
+static void preload_index(struct index_state *index, const char **pathspec)
+{
+	; /* nothing */
+}
+#else
+
 #include <pthread.h>
 
 /*
@@ -81,6 +89,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
 			die("unable to join threaded lstat");
 	}
 }
+#endif
 
 int read_index_preload(struct index_state *index, const char **pathspec)
 {
-- 
1.6.0.2.229.g1293c.dirty

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

* [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-01  8:29                                   ` Johannes Sixt
                                                       ` (2 preceding siblings ...)
  2008-12-01 16:09                                     ` Mike Ralphson
@ 2008-12-01 16:13                                     ` Mike Ralphson
  2008-12-02  7:41                                       ` Johannes Sixt
  3 siblings, 1 reply; 44+ messages in thread
From: Mike Ralphson @ 2008-12-01 16:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Mike Ralphson, j.sixt

From: Junio C Hamano <gitster@pobox.com>

 This introduces make variable NO_PTHREADS for platforms that lack the
 support for pthreads library or people who do not want to use it for
 whatever reason.  When defined, it makes the multi-threaded index
 preloading into a no-op, and also disables threaded delta searching by
 pack-objects.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Mike Ralphson <mike@abacus.co.uk>
---

* I notice a handful platforms do not define THREADED_DELTA_SEARCH, and
 on them Linus's preload-index.c is the first source file that includes
 <pthreads.h>, which may result in breakages.

 Made the default for AIX <5 and Mingw

 With correct commit message. Sorry for the previous attempt.

 Makefile        |   17 ++++++++++++++++-
 config.mak.in   |    1 +
 configure.ac    |    5 +++++
 preload-index.c |    9 +++++++++
 4 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index d1e2116..5a69a41 100644
--- a/Makefile
+++ b/Makefile
@@ -90,6 +90,8 @@ all::
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define NO_PTHREADS if you do not have or do not want to use Pthreads.
+#
 # Define NO_PREAD if you have a problem with pread() system call (e.g.
 # cygwin.dll before v1.5.22).
 #
@@ -164,6 +166,7 @@ uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
 uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
 uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
 uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
+uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
 
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
@@ -722,6 +725,11 @@ ifeq ($(uname_S),AIX)
 	INTERNAL_QSORT = UnfortunatelyYes
 	NEEDS_LIBICONV=YesPlease
 	BASIC_CFLAGS += -D_LARGE_FILES
+	ifneq ($(shell expr "$(uname_V)" : '[1234]'),1)
+		THREADED_DELTA_SEARCH = YesPlease
+	else
+		NO_PTHREADS = YesPlease
+	endif
 endif
 ifeq ($(uname_S),GNU)
 	# GNU/Hurd
@@ -766,6 +774,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_STRCASESTR = YesPlease
 	NO_STRLCPY = YesPlease
 	NO_MEMMEM = YesPlease
+	NO_PTHREADS = YesPlease
 	NEEDS_LIBICONV = YesPlease
 	OLD_ICONV = YesPlease
 	NO_C99_FORMAT = YesPlease
@@ -1017,9 +1026,15 @@ ifdef INTERNAL_QSORT
 	COMPAT_OBJS += compat/qsort.o
 endif
 
+ifdef NO_PTHREADS
+	THREADED_DELTA_SEARCH =
+	BASIC_CFLAGS += -DNO_PTHREADS
+else
+	EXTLIBS += $(PTHREAD_LIBS)
+endif
+
 ifdef THREADED_DELTA_SEARCH
 	BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH
-	EXTLIBS += $(PTHREAD_LIBS)
 	LIB_OBJS += thread-utils.o
 endif
 ifdef DIR_HAS_BSD_GROUP_SEMANTICS
diff --git a/config.mak.in b/config.mak.in
index ea7705c..14dfb21 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -51,4 +51,5 @@ OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
 FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@
 SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
+NO_PTHREADS=@NO_PTHREADS@
 PTHREAD_LIBS=@PTHREAD_LIBS@
diff --git a/configure.ac b/configure.ac
index 4256742..8821b50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -490,6 +490,8 @@ AC_SUBST(NO_MKDTEMP)
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
+# Define NO_PTHREADS if we do not have pthreads
+#
 # Define PTHREAD_LIBS to the linker flag used for Pthread support.
 AC_LANG_CONFTEST([AC_LANG_PROGRAM(
   [[#include <pthread.h>]],
@@ -502,9 +504,12 @@ else
  ${CC} -lpthread conftest.c -o conftest.o > /dev/null 2>&1
  if test $? -eq 0;then
   PTHREAD_LIBS="-lpthread"
+ else
+  NO_PTHREADS=UnfortunatelyYes
  fi
 fi
 AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(NO_PTHREADS)
 
 ## Site configuration (override autodetection)
 ## --with-PACKAGE[=ARG] and --without-PACKAGE
diff --git a/preload-index.c b/preload-index.c
index a685583..88edc5f 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -2,6 +2,14 @@
  * Copyright (C) 2008 Linus Torvalds
  */
 #include "cache.h"
+
+#ifdef NO_PTHREADS
+static void preload_index(struct index_state *index, const char **pathspec)
+{
+	; /* nothing */
+}
+#else
+
 #include <pthread.h>
 
 /*
@@ -81,6 +89,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
 			die("unable to join threaded lstat");
 	}
 }
+#endif
 
 int read_index_preload(struct index_state *index, const char **pathspec)
 {
-- 
1.6.0.2.229.g1293c.dirty

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-01 16:13                                     ` Mike Ralphson
@ 2008-12-02  7:41                                       ` Johannes Sixt
  2008-12-03  2:18                                         ` Junio C Hamano
  0 siblings, 1 reply; 44+ messages in thread
From: Johannes Sixt @ 2008-12-02  7:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Mike Ralphson

Mike Ralphson schrieb:
> From: Junio C Hamano <gitster@pobox.com>
> 
>  This introduces make variable NO_PTHREADS for platforms that lack the
>  support for pthreads library or people who do not want to use it for
>  whatever reason.  When defined, it makes the multi-threaded index
>  preloading into a no-op, and also disables threaded delta searching by
>  pack-objects.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
> Signed-off-by: Mike Ralphson <mike@abacus.co.uk>
> ---

You can add

Tested-by: Johannes Sixt <j6t@kdbg.org> (AIX 4.3.x)

-- Hannes

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

* Re: [PATCH] Makefile: introduce NO_PTHREADS
  2008-12-02  7:41                                       ` Johannes Sixt
@ 2008-12-03  2:18                                         ` Junio C Hamano
  0 siblings, 0 replies; 44+ messages in thread
From: Junio C Hamano @ 2008-12-03  2:18 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git, Mike Ralphson

Thanks, both.

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

end of thread, other threads:[~2008-12-03  2:19 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-12  9:29 hosting git on a nfs Thomas Koch
2008-11-12 10:10 ` Julian Phillips
2008-11-12 20:31   ` Brandon Casey
2008-11-12 17:36 ` David Brown
2008-11-12 18:14   ` Linus Torvalds
2008-11-13 18:18     ` J. Bruce Fields
2008-11-13 18:32     ` James Pickens
2008-11-13 20:18       ` Linus Torvalds
2008-11-13 21:05         ` Linus Torvalds
2008-11-13 23:23           ` James Pickens
2008-11-13 23:48             ` Linus Torvalds
2008-11-13 23:23           ` Julian Phillips
2008-11-13 23:42           ` Linus Torvalds
2008-11-14  0:04             ` Julian Phillips
2008-11-14  0:14             ` Brandon Casey
2008-11-14  0:38               ` Linus Torvalds
2008-11-14  0:59                 ` Pieter de Bie
2008-11-14  1:15                 ` Linus Torvalds
2008-11-14  3:33                   ` James Pickens
2008-11-14  5:01                     ` Linus Torvalds
2008-11-14 13:01                   ` Michael J Gruber
2008-11-14 14:31                   ` Kyle Moffett
2008-11-14 18:32                   ` Brandon Casey
2008-11-14 19:23                     ` Linus Torvalds
2008-11-14 20:14                       ` Junio C Hamano
2008-11-14 23:10                         ` Linus Torvalds
2008-11-15 12:08                       ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano
2008-11-15 17:15                         ` Linus Torvalds
2008-11-17 10:03                           ` Mike Ralphson
2008-11-17 10:18                             ` Junio C Hamano
2008-11-17 10:34                             ` Johannes Sixt
2008-11-17 10:45                               ` Mike Ralphson
2008-11-17 11:25                                 ` Johannes Sixt
2008-12-01  8:29                                   ` Johannes Sixt
2008-12-01  8:48                                     ` dhruva
2008-12-01  9:57                                     ` Mike Ralphson
2008-12-01 16:09                                     ` Mike Ralphson
2008-12-01 16:13                                     ` Mike Ralphson
2008-12-02  7:41                                       ` Johannes Sixt
2008-12-03  2:18                                         ` Junio C Hamano
2008-11-17 16:38                           ` Junio C Hamano
2008-11-17 16:47                             ` Linus Torvalds
2008-11-17 17:01                               ` Fix index preloading for racy dirty case Linus Torvalds
2008-11-17 16:41                           ` [PATCH] Makefile: introduce NO_PTHREADS Junio C Hamano

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