瀏覽代碼

Add starpu_data_evict_from_node function

Samuel Thibault 3 年之前
父節點
當前提交
7e08ea77f9
共有 4 個文件被更改,包括 61 次插入3 次删除
  1. 1 0
      ChangeLog
  2. 9 0
      include/starpu_data.h
  3. 32 0
      src/datawizard/memalloc.c
  4. 19 3
      tests/disk/mem_reclaim.c

+ 1 - 0
ChangeLog

@@ -53,6 +53,7 @@ New features:
   * Add peek_data interface method.
   * Add STARPU_MPI_REDUX
   * Add starpu_data_query_status2 function.
+  * Add starpu_data_evict_from_node function.
   * Add a StarPU Eclipse Plugin
 
 Small features:

+ 9 - 0
include/starpu_data.h

@@ -495,6 +495,15 @@ unsigned starpu_data_is_on_node(starpu_data_handle_t handle, unsigned node);
 void starpu_data_wont_use(starpu_data_handle_t handle);
 
 /**
+   Advise StarPU to evict \p handle from the memory node \p node
+   StarPU will thus write its value back to its home node, before evicting it.
+   This may however fail if e.g. some task is still working on it.
+
+   If the eviction was successful, 0 is returned ; -1 is returned otherwise.
+*/
+int starpu_data_evict_from_node(starpu_data_handle_t handle, unsigned node);
+
+/**
    Set the write-through mask of the data \p handle (and
    its children), i.e. a bitmask of nodes where the data should be always
    replicated after modification. It also prevents the data from being

+ 32 - 0
src/datawizard/memalloc.c

@@ -1104,6 +1104,38 @@ size_t _starpu_free_all_automatically_allocated_buffers(unsigned node)
 	return _starpu_memory_reclaim_generic(node, 1, 0, STARPU_FETCH);
 }
 
+int starpu_data_evict_from_node(starpu_data_handle_t handle, unsigned node)
+{
+	STARPU_ASSERT(node < STARPU_MAXNODES);
+	struct _starpu_data_replicate *replicate;
+	if (handle->per_worker)
+		replicate = &handle->per_worker[node];
+	else
+		replicate = &handle->per_node[node];
+
+	_starpu_spin_lock(&handle->header_lock);
+
+	struct _starpu_mem_chunk *mc = replicate->mc;
+	int ret = -1;
+
+	if (!mc)
+		/* Nothing there */
+		goto out;
+
+	_starpu_spin_lock(&mc_lock[node]);
+	if (mc->remove_notify)
+		/* Somebody already working here */
+		goto out_mc;
+	if (try_to_throw_mem_chunk(mc, node, NULL, 0, STARPU_FETCH) == 0)
+		goto out_mc;
+	ret = 0;
+out_mc:
+	_starpu_spin_unlock(&mc_lock[node]);
+out:
+	_starpu_spin_unlock(&handle->header_lock);
+	return ret;
+}
+
 /* Periodic tidy of available memory  */
 void starpu_memchunk_tidy(unsigned node)
 {

+ 19 - 3
tests/disk/mem_reclaim.c

@@ -40,13 +40,13 @@
 
 #ifdef STARPU_QUICK_CHECK
 #  define NDATA 4
-#  define NITER 16
+#  define NITER 8
 #elif !defined(STARPU_LONG_CHECK)
 #  define NDATA 32
-#  define NITER 256
+#  define NITER 128
 #else
 #  define NDATA 128
-#  define NITER 1024
+#  define NITER 512
 #endif
 #  define MEMSIZE 1
 #  define MEMSIZE_STR "1"
@@ -180,6 +180,22 @@ int dotest(struct starpu_disk_ops *ops, char *base, void (*vector_data_register)
 	}
 	memset(values, 0, sizeof(values));
 
+	/* Work out of core */
+	for (i = 0; i < NITER; i++)
+	{
+		j = rand()%NDATA;
+		starpu_task_insert(&inc_cl, STARPU_RW, handles[j], STARPU_VALUE, &j, sizeof(j), 0);
+	}
+	starpu_task_wait_for_all();
+
+	/* forcibly evict some data, just for fun */
+	for (i = 0; i < NDATA; i++)
+	{
+		if ((rand() % 2) == 0)
+			starpu_data_evict_from_node(handles[i], STARPU_MAIN_RAM);
+	}
+
+	/* And work out of core again */
 	for (i = 0; i < NITER; i++)
 	{
 		j = rand()%NDATA;