浏览代码

Add experimental STARPU_DIDUSE_BARRIER environment variable support

Samuel Thibault 8 年之前
父节点
当前提交
ad53cb20ee

+ 9 - 0
doc/doxygen/chapters/501_environment_variables.doxy

@@ -743,6 +743,15 @@ GPUs (or in main memory, when using out of core), when performing an asynchronou
 writeback pass. The default is 10%.
 </dd>
 
+<dt>STARPU_DIDUSE_BARRIER</dt>
+<dd>
+\anchor STARPU_DIDUSE_BARRIER
+\addindex __env__STARPU_DIDUSE_BARRIER
+When set to 1, StarPU will never evict a piece of data if it has not been used
+by at least one task. This avoids odd behaviors under high memory pressure, but
+can lead to deadlocks, so is to be considered experimental only.
+</dd>
+
 <dt>STARPU_DISK_SWAP</dt>
 <dd>
 \anchor STARPU_DISK_SWAP

+ 13 - 1
src/datawizard/memalloc.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2009-2016  Université de Bordeaux
+ * Copyright (C) 2009-2017  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
  * Copyright (C) 2016  Inria
  *
@@ -33,6 +33,9 @@ static unsigned target_clean_p;
 /* Whether CPU memory has been explicitly limited by user */
 static int limit_cpu_mem;
 
+/* Prevent memchunks from being evicted from memory before they are actually used */
+static int diduse_barrier;
+
 /* This per-node RW-locks protect mc_list and memchunk_cache entries */
 /* Note: handle header lock is always taken before this (normal add/remove case) */
 static struct _starpu_spinlock mc_lock[STARPU_MAXNODES];
@@ -133,6 +136,7 @@ void _starpu_init_mem_chunk_lists(void)
 	minimum_clean_p = starpu_get_env_number_default("STARPU_MINIMUM_CLEAN_BUFFERS", 5);
 	target_clean_p = starpu_get_env_number_default("STARPU_TARGET_CLEAN_BUFFERS", 10);
 	limit_cpu_mem = starpu_get_env_number("STARPU_LIMIT_CPU_MEM");
+	diduse_barrier = starpu_get_env_number_default("STARPU_DIDUSE_BARRIER", 0);
 }
 
 void _starpu_deinit_mem_chunk_lists(void)
@@ -443,6 +447,10 @@ static size_t try_to_free_mem_chunk(struct _starpu_mem_chunk *mc, unsigned node)
 	if ((int) node == handle->home_node)
 		return 0;
 
+	if (diduse_barrier && !mc->diduse)
+		/* Hasn't been used yet, avoid evicting it */
+		return 0;
+
 	/* REDUX memchunk */
 	if (mc->relaxed_coherency == 2)
 	{
@@ -1160,6 +1168,7 @@ static struct _starpu_mem_chunk *_starpu_memchunk_init(struct _starpu_data_repli
 	mc->chunk_interface = NULL;
 	mc->size_interface = interface_size;
 	mc->remove_notify = NULL;
+	mc->diduse = 0;
 
 	return mc;
 }
@@ -1455,6 +1464,7 @@ void _starpu_memchunk_recently_used(struct _starpu_mem_chunk *mc, unsigned node)
 		/* user-allocated memory */
 		return;
 	_starpu_spin_lock(&mc_lock[node]);
+	mc->diduse = 1;
 	MC_LIST_ERASE(node, mc);
 	MC_LIST_PUSH_BACK(node, mc);
 	_starpu_spin_unlock(&mc_lock[node]);
@@ -1468,6 +1478,8 @@ void _starpu_memchunk_wont_use(struct _starpu_mem_chunk *mc, unsigned node)
 		/* user-allocated memory */
 		return;
 	_starpu_spin_lock(&mc_lock[node]);
+	/* Avoid preventing it from being evicted */
+	mc->diduse = 1;
 	MC_LIST_ERASE(node, mc);
 	/* Caller will schedule a clean transfer */
 	mc->clean = 1;

+ 4 - 1
src/datawizard/memalloc.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2009-2010, 2012-2015  Université de Bordeaux
+ * Copyright (C) 2009-2010, 2012-2015, 2017  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013  CNRS
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -73,6 +73,9 @@ LIST_TYPE(_starpu_mem_chunk,
 	 * remove this entry from the mc_list, so we know we have to restart
 	 * from zero. This is protected by the corresponding mc_lock.  */
 	struct _starpu_mem_chunk **remove_notify;
+
+	/* Was this chunk used since it got allocated?  */
+	int diduse;
 )
 
 void _starpu_init_mem_chunk_lists(void);

+ 4 - 0
tests/datawizard/allocate.c

@@ -42,6 +42,10 @@ int test_prefetch(unsigned memnodes)
 	unsigned i;
 	starpu_ssize_t available_size;
 
+	if (starpu_get_env_number_default("STARPU_DIDUSE_BARRIER", 0))
+		/* This would hang */
+		return STARPU_TEST_SKIPPED;
+
 	buffers[0] = malloc(SIZE_ALLOC*1024*512);
 	STARPU_ASSERT(buffers[0]);
 

+ 4 - 0
tests/disk/mem_reclaim.c

@@ -141,6 +141,10 @@ int dotest(struct starpu_disk_ops *ops, char *base, void (*vector_data_register)
 {
 	int *A, *C;
 	starpu_data_handle_t handles[NDATA];
+j
+	if (starpu_get_env_number_default("STARPU_DIDUSE_BARRIER", 0))
+		/* This would hang */
+		return STARPU_TEST_SKIPPED;
 
 	FPRINTF(stderr, "Testing <%s>\n", text);
 	/* Initialize StarPU without GPU devices to make sure the memory of the GPU devices will not be used */