Hi Jakub!

On 2019-11-06T18:43:39+0000, Julian Brown <jul...@codesourcery.com> wrote:
> In particular, [a new big patch] incorporates the idea [...]
> relating to adding the new "attach_count" field to the memory-mapping
> splay tree key type without growing that structure in the common case
> (i.e. when structure components are not being mapped, or for OpenMP).
> In short, a new auxiliary structure is added containing the previous
> "link_key" and "attach_count" fields: so, you can either have both
> pointers (though of course one of them may be NULL), or in the common
> case no aux pointer at all, so no growth in the base struct size.

That was in response to:

> On Fri, 18 Oct 2019 18:47:08 +0200
> Thomas Schwinge <tho...@codesourcery.com> wrote:
>> While reviewing
>> <http://mid.mail-archive.com/20191003163505.49997-2-julian@codesourcery.com>
>> "OpenACC reference count overhaul", I've just now stumbled over one
>> thing that originally was designed here:
>> 
>> On 2018-12-10T19:41:37+0000, Julian Brown <jul...@codesourcery.com>
>> wrote:
>> > On Fri, 7 Dec 2018 14:50:19 +0100
>> > Jakub Jelinek <ja...@redhat.com> wrote:
>> >  
>> >> On Fri, Nov 30, 2018 at 03:41:09AM -0800, Julian Brown wrote:  
>> >> > @@ -918,8 +920,13 @@ struct splay_tree_key_s {
>> >> >    uintptr_t tgt_offset;
>> >> >    /* Reference count.  */
>> >> >    uintptr_t refcount;
>> >> > -  /* Dynamic reference count.  */
>> >> > -  uintptr_t dynamic_refcount;
>> >> > +  /* Reference counts beyond those that represent genuine references 
>> >> > in the
>> >> > +     linked splay tree key/target memory structures, e.g. for multiple 
>> >> > OpenACC
>> >> > +     "present increment" operations (via "acc enter data") refering to 
>> >> > the same
>> >> > +     host-memory block.  */
>> >> > +  uintptr_t virtual_refcount;
>> >> > +  /* For a block with attached pointers, the attachment counters for 
>> >> > each.  */
>> >> > +  unsigned short *attach_count;
>> >> >    /* Pointer to the original mapping of "omp declare target link" 
>> >> > object.  */
>> >> >    splay_tree_key link_key;
>> >> >  };    
>> >> 
>> >> This is something I'm worried about a lot, the nodes keep growing
>> >> way too much.  
>> 
>> Is that just a would-be-nice-to-avoid, or is it an actual problem?
>> 
>> If the latter, can we maybe move some data into on-the-side data
>> structures, say an associative array keyed by [something suitable]?  I
>> would assume that compared to actual host to/from device data movement
>> (or even lookup etc.), lookup of values from such an associative array
>> should be relatively cheap?
>
> I'd be extremely wary of adding a completely separate off-the-side
> structure to keep track of attachment counters: the reference-counting
> behaviour is already complicated enough, and the risk of messing things
> up with another indirectly-linked structure to keep track of is too
> high (never mind the extra runtime overhead).

(Well, ACK; it was just an idea to think in a different direction maybe.)

> With the approach in this
> patch, at least the extra info for link_key/attach_count is directly
> accessible from the splay tree key struct via pointer indirection.
>
> This version entails slight additional overhead (another malloc'd
> block and another pointer indirection) for the link_key field (and also
> for the attach_count pointer). I've not benchmarked memory use or
> performance though, so I'm not sure how much impact this has on real
> code.

I extracted the changes related to that from Julian's big patch, see
attached "In 'libgomp/target.c', 'struct splay_tree_key_s', use 'struct
splay_tree_aux' for infrequently-used or API-specific data ".  Is this OK
to commit?  If approving this patch, please respond with "Reviewed-by:
NAME <EMAIL>" so that your effort will be recorded in the commit log, see
<https://gcc.gnu.org/wiki/Reviewed-by>.


As part of the OpenACC manual deep copy changes, we'll then later apply:

     struct splay_tree_aux {
       /* Pointer to the original mapping of "omp declare target link" object.  
*/
       splay_tree_key link_key;
    +  /* For a block with attached pointers, the attachment counters for each.
    +     Only used for OpenACC.  */
    +  uintptr_t *attach_count;
     };


Grüße
 Thomas


From 6f81ae8189c5a53d9ab414363bfefd249b78e7c1 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tho...@codesourcery.com>
Date: Tue, 17 Dec 2019 16:11:40 +0100
Subject: [PATCH] In 'libgomp/target.c', 'struct splay_tree_key_s', use 'struct
 splay_tree_aux' for infrequently-used or API-specific data

---
 libgomp/libgomp.h | 10 ++++++++--
 libgomp/target.c  | 23 ++++++++++++++++-------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index b2cd07dfa67..d65a1fa250b 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -989,6 +989,13 @@ struct target_mem_desc {
 #define OFFSET_POINTER (~(uintptr_t) 1)
 #define OFFSET_STRUCT (~(uintptr_t) 2)
 
+/* Auxiliary structure for infrequently-used or API-specific data.  */
+
+struct splay_tree_aux {
+  /* Pointer to the original mapping of "omp declare target link" object.  */
+  splay_tree_key link_key;
+};
+
 struct splay_tree_key_s {
   /* Address of the host object.  */
   uintptr_t host_start;
@@ -1002,8 +1009,7 @@ struct splay_tree_key_s {
   uintptr_t refcount;
   /* Dynamic reference count.  */
   uintptr_t dynamic_refcount;
-  /* Pointer to the original mapping of "omp declare target link" object.  */
-  splay_tree_key link_key;
+  struct splay_tree_aux *aux;
 };
 
 /* The comparison function.  */
diff --git a/libgomp/target.c b/libgomp/target.c
index 795b9351134..d00334ce9e6 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -972,13 +972,15 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
 				      kind & typemask, cbufp);
 	    else
 	      {
-		k->link_key = NULL;
+		k->aux = NULL;
 		if (n && n->refcount == REFCOUNT_LINK)
 		  {
 		    /* Replace target address of the pointer with target address
 		       of mapped object in the splay tree.  */
 		    splay_tree_remove (mem_map, n);
-		    k->link_key = n;
+		    k->aux
+		      = gomp_malloc_cleared (sizeof (struct splay_tree_aux));
+		    k->aux->link_key = n;
 		  }
 		size_t align = (size_t) 1 << (kind >> rshift);
 		tgt->list[i].key = k;
@@ -1096,7 +1098,7 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
 				kind);
 		  }
 
-		if (k->link_key)
+		if (k->aux && k->aux->link_key)
 		  {
 		    /* Set link pointer on target to the device address of the
 		       mapped object.  */
@@ -1211,8 +1213,14 @@ gomp_remove_var_internal (struct gomp_device_descr *devicep, splay_tree_key k,
 {
   bool is_tgt_unmapped = false;
   splay_tree_remove (&devicep->mem_map, k);
-  if (k->link_key)
-    splay_tree_insert (&devicep->mem_map, (splay_tree_node) k->link_key);
+  if (k->aux)
+    {
+      if (k->aux->link_key)
+	splay_tree_insert (&devicep->mem_map,
+			   (splay_tree_node) k->aux->link_key);
+      free (k->aux);
+      k->aux = NULL;
+    }
   if (aq)
     devicep->openacc.async.queue_callback_func (aq, gomp_unref_tgt_void,
 						(void *) k->tgt);
@@ -1439,7 +1447,7 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
       k->tgt_offset = target_table[i].start;
       k->refcount = REFCOUNT_INFINITY;
       k->dynamic_refcount = 0;
-      k->link_key = NULL;
+      k->aux = NULL;
       array->left = NULL;
       array->right = NULL;
       splay_tree_insert (&devicep->mem_map, array);
@@ -1472,7 +1480,7 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
       k->tgt_offset = target_var->start;
       k->refcount = target_size & link_bit ? REFCOUNT_LINK : REFCOUNT_INFINITY;
       k->dynamic_refcount = 0;
-      k->link_key = NULL;
+      k->aux = NULL;
       array->left = NULL;
       array->right = NULL;
       splay_tree_insert (&devicep->mem_map, array);
@@ -2742,6 +2750,7 @@ omp_target_associate_ptr (const void *host_ptr, const void *device_ptr,
       k->tgt_offset = (uintptr_t) device_ptr + device_offset;
       k->refcount = REFCOUNT_INFINITY;
       k->dynamic_refcount = 0;
+      k->aux = NULL;
       array->left = NULL;
       array->right = NULL;
       splay_tree_insert (&devicep->mem_map, array);
-- 
2.17.1

Attachment: signature.asc
Description: PGP signature

Reply via email to