Provides the default value for the `--guess` or `--no-guess`
option in `git checkout` and `git switch`. See
linkgit:git-switch[1] and linkgit:git-checkout[1].
+
+checkout.workers::
+ The number of parallel workers to use when updating the working tree.
+ The default is one, i.e. sequential execution. If set to a value less
+ than one, Git will use as many workers as the number of logical cores
+ available. This setting and `checkout.thresholdForParallelism` affect
+ all commands that perform checkout. E.g. checkout, clone, reset,
+ sparse-checkout, etc.
++
+Note: parallel checkout usually delivers better performance for repositories
+located on SSDs or over NFS. For repositories on spinning disks and/or machines
+with a small number of cores, the default sequential checkout often performs
+better. The size and compression level of a repository might also influence how
+well the parallel version performs.
+
+checkout.thresholdForParallelism::
+ When running parallel checkout with a small number of files, the cost
+ of subprocess spawning and inter-process communication might outweigh
+ the parallelization gains. This setting allows to define the minimum
+ number of files for which parallel checkout should be attempted. The
+ default is 100.
#include "cache.h"
+#include "config.h"
#include "entry.h"
#include "parallel-checkout.h"
#include "pkt-line.h"
#include "run-command.h"
#include "sigchain.h"
#include "streaming.h"
+#include "thread-utils.h"
struct pc_worker {
struct child_process cp;
return parallel_checkout.status;
}
+static const int DEFAULT_THRESHOLD_FOR_PARALLELISM = 100;
+static const int DEFAULT_NUM_WORKERS = 1;
+
+void get_parallel_checkout_configs(int *num_workers, int *threshold)
+{
+ if (git_config_get_int("checkout.workers", num_workers))
+ *num_workers = DEFAULT_NUM_WORKERS;
+ else if (*num_workers < 1)
+ *num_workers = online_cpus();
+
+ if (git_config_get_int("checkout.thresholdForParallelism", threshold))
+ *threshold = DEFAULT_THRESHOLD_FOR_PARALLELISM;
+}
+
void init_parallel_checkout(void)
{
if (parallel_checkout.status != PC_UNINITIALIZED)
write_pc_item(¶llel_checkout.items[i], state);
}
-static const int DEFAULT_NUM_WORKERS = 2;
-
-int run_parallel_checkout(struct checkout *state)
+int run_parallel_checkout(struct checkout *state, int num_workers, int threshold)
{
- int ret, num_workers = DEFAULT_NUM_WORKERS;
+ int ret;
if (parallel_checkout.status != PC_ACCEPTING_ENTRIES)
BUG("cannot run parallel checkout: uninitialized or already running");
if (parallel_checkout.nr < num_workers)
num_workers = parallel_checkout.nr;
- if (num_workers <= 1) {
+ if (num_workers <= 1 || parallel_checkout.nr < threshold) {
write_items_sequentially(state);
} else {
struct pc_worker *workers = setup_workers(state, num_workers);
};
enum pc_status parallel_checkout_status(void);
+void get_parallel_checkout_configs(int *num_workers, int *threshold);
/*
* Put parallel checkout into the PC_ACCEPTING_ENTRIES state. Should be used
*/
int enqueue_checkout(struct cache_entry *ce, struct conv_attrs *ca);
-/* Write all the queued entries, returning 0 on success.*/
-int run_parallel_checkout(struct checkout *state);
+/*
+ * Write all the queued entries, returning 0 on success. If the number of
+ * entries is smaller than the specified threshold, the operation is performed
+ * sequentially.
+ */
+int run_parallel_checkout(struct checkout *state, int num_workers, int threshold);
/****************************************************************
* Interface with checkout--worker
int errs = 0;
struct progress *progress;
struct checkout state = CHECKOUT_INIT;
- int i;
+ int i, pc_workers, pc_threshold;
trace_performance_enter();
state.force = 1;
oid_array_clear(&to_fetch);
}
+ get_parallel_checkout_configs(&pc_workers, &pc_threshold);
+
enable_delayed_checkout(&state);
- init_parallel_checkout();
+ if (pc_workers > 1)
+ init_parallel_checkout();
for (i = 0; i < index->cache_nr; i++) {
struct cache_entry *ce = index->cache[i];
}
}
stop_progress(&progress);
- errs |= run_parallel_checkout(&state);
+ if (pc_workers > 1)
+ errs |= run_parallel_checkout(&state, pc_workers, pc_threshold);
errs |= finish_delayed_checkout(&state, NULL);
git_attr_set_direction(GIT_ATTR_CHECKIN);