From: Victor Leschuk <vleschuk@gmail.com>
To: git@vger.kernel.org
Cc: Victor Leschuk <vleschuk@accesssoftek.com>
Subject: [PATCH v3] Add git-grep threads param
Date: Mon, 26 Oct 2015 15:32:13 +0300 [thread overview]
Message-ID: <1445862733-838-1-git-send-email-vleschuk@accesssoftek.com> (raw)
Make number of git-grep worker threads a configuration parameter.
According to several tests on systems with different number of CPU cores
the hard-coded number of 8 threads is not optimal for all systems:
tuning this parameter can significantly speed up grep performance.
Signed-off-by: Victor Leschuk <vleschuk@accesssoftek.com>
---
Documentation/config.txt | 4 ++++
Documentation/git-grep.txt | 4 ++++
builtin/grep.c | 34 ++++++++++++++++++++++++++--------
contrib/completion/git-completion.bash | 1 +
grep.c | 10 ++++++++++
grep.h | 2 ++
6 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 391a0c3..1c95587 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1447,6 +1447,10 @@ grep.extendedRegexp::
option is ignored when the 'grep.patternType' option is set to a value
other than 'default'.
+grep.threads::
+ Number of grep worker threads, use it to tune up performance on
+ multicore machines. Default value is 8.
+
gpg.program::
Use this custom program instead of "gpg" found on $PATH when
making or verifying a PGP signature. The program must support the
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 4a44d6d..fbd4f83 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -22,6 +22,7 @@ SYNOPSIS
[--color[=<when>] | --no-color]
[--break] [--heading] [-p | --show-function]
[-A <post-context>] [-B <pre-context>] [-C <context>]
+ [--threads <num>]
[-W | --function-context]
[-f <file>] [-e] <pattern>
[--and|--or|--not|(|)|-e <pattern>...]
@@ -220,6 +221,9 @@ OPTIONS
Show <num> leading lines, and place a line containing
`--` between contiguous groups of matches.
+--threads <num>::
+ Set number of worker threads to <num>. Default is 8.
+
-W::
--function-context::
Show the surrounding text from the previous line containing a
diff --git a/builtin/grep.c b/builtin/grep.c
index d04f440..5ef1b07 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -27,8 +27,7 @@ static char const * const grep_usage[] = {
static int use_threads = 1;
#ifndef NO_PTHREADS
-#define THREADS 8
-static pthread_t threads[THREADS];
+static pthread_t *threads;
/* We use one producer thread and THREADS consumer
* threads. The producer adds struct work_items to 'todo' and the
@@ -206,7 +205,8 @@ static void start_threads(struct grep_opt *opt)
strbuf_init(&todo[i].out, 0);
}
- for (i = 0; i < ARRAY_SIZE(threads); i++) {
+ threads = xcalloc(opt->num_threads, sizeof(pthread_t));
+ for (i = 0; i < opt->num_threads; i++) {
int err;
struct grep_opt *o = grep_opt_dup(opt);
o->output = strbuf_out;
@@ -220,7 +220,7 @@ static void start_threads(struct grep_opt *opt)
}
}
-static int wait_all(void)
+static int wait_all(struct grep_opt *opt)
{
int hit = 0;
int i;
@@ -238,12 +238,14 @@ static int wait_all(void)
pthread_cond_broadcast(&cond_add);
grep_unlock();
- for (i = 0; i < ARRAY_SIZE(threads); i++) {
+ for (i = 0; i < opt->num_threads; i++) {
void *h;
pthread_join(threads[i], &h);
hit |= (int) (intptr_t) h;
}
+ free(threads);
+
pthread_mutex_destroy(&grep_mutex);
pthread_mutex_destroy(&grep_read_mutex);
pthread_mutex_destroy(&grep_attr_mutex);
@@ -256,7 +258,7 @@ static int wait_all(void)
}
#else /* !NO_PTHREADS */
-static int wait_all(void)
+static int wait_all(struct grep_opt *opt)
{
return 0;
}
@@ -702,6 +704,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
N_("show <n> context lines before matches")),
OPT_INTEGER('A', "after-context", &opt.post_context,
N_("show <n> context lines after matches")),
+ OPT_INTEGER(0, "threads", &opt.num_threads,
+ N_("use <n> worker threads")),
OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"),
context_callback),
OPT_BOOL('p', "show-function", &opt.funcname,
@@ -832,8 +836,22 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
}
#ifndef NO_PTHREADS
- if (list.nr || cached || online_cpus() == 1)
+ if (!opt.num_threads) {
+ use_threads = 0; /* User explicitely told not to use threads */
+ }
+ else if (list.nr || cached) {
+ use_threads = 0; /* Can not multi-thread object lookup */
+ }
+ else if (opt.num_threads >= 0) {
+ use_threads = 1; /* User explicitely set the number of threads */
+ }
+ else if (online_cpus() <= 1) {
use_threads = 0;
+ }
+ else {
+ use_threads = 1;
+ opt.num_threads = GREP_NUM_THREADS_DEFAULT;
+ }
#else
use_threads = 0;
#endif
@@ -910,7 +928,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
}
if (use_threads)
- hit |= wait_all();
+ hit |= wait_all(&opt);
if (hit && show_in_pager)
run_pager(&opt, prefix);
free_grep_patterns(&opt);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 482ca84..390d9c0 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1310,6 +1310,7 @@ _git_grep ()
--full-name --line-number
--extended-regexp --basic-regexp --fixed-strings
--perl-regexp
+ --threads
--files-with-matches --name-only
--files-without-match
--max-depth
diff --git a/grep.c b/grep.c
index 7b2b96a..b53fb14 100644
--- a/grep.c
+++ b/grep.c
@@ -40,6 +40,7 @@ void init_grep_defaults(void)
color_set(opt->color_selected, "");
color_set(opt->color_sep, GIT_COLOR_CYAN);
opt->color = -1;
+ opt->num_threads = -1;
}
static int parse_pattern_type_arg(const char *opt, const char *arg)
@@ -124,6 +125,14 @@ int grep_config(const char *var, const char *value, void *cb)
return config_error_nonbool(var);
return color_parse(value, color);
}
+
+ if (!strcmp(var, "grep.threads")) {
+ int threads = git_config_int(var, value);
+ if (threads < 0)
+ die("invalid number of threads specified (%d)", threads);
+ opt->num_threads = threads;
+ return 0;
+ }
return 0;
}
@@ -150,6 +159,7 @@ void grep_init(struct grep_opt *opt, const char *prefix)
opt->pathname = def->pathname;
opt->regflags = def->regflags;
opt->relative = def->relative;
+ opt->num_threads = def->num_threads;
color_set(opt->color_context, def->color_context);
color_set(opt->color_filename, def->color_filename);
diff --git a/grep.h b/grep.h
index 95f197a..bb20456 100644
--- a/grep.h
+++ b/grep.h
@@ -132,6 +132,8 @@ struct grep_opt {
unsigned pre_context;
unsigned post_context;
unsigned last_shown;
+#define GREP_NUM_THREADS_DEFAULT 8
+ int num_threads;
int show_hunk_mark;
int file_break;
int heading;
--
2.6.2.281.g222e106.dirty
next reply other threads:[~2015-10-26 12:32 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-26 12:32 Victor Leschuk [this message]
2015-10-26 19:32 ` [PATCH v3] Add git-grep threads param John Keeping
2015-10-27 5:25 ` Victor Leschuk
2015-10-27 11:52 ` John Keeping
2015-10-27 13:54 ` Victor Leschuk
2015-10-27 14:11 ` John Keeping
[not found] ` <CA+55aFwrU25x25XrRODgS1oRXqN60rmYPiXLgfs3mqRco4Oi9A@mail.gmail.com>
2015-10-27 9:14 ` Victor Leschuk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1445862733-838-1-git-send-email-vleschuk@accesssoftek.com \
--to=vleschuk@gmail.com \
--cc=git@vger.kernel.org \
--cc=vleschuk@accesssoftek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is 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).