[beast] BIRNET: improve malloc_aligned to take cache line size into account.



commit 78fc445e37dea1be9cfb2cf4e3efaf483b60995c
Author: Stefan Westerfeld <stefan space twc de>
Date:   Sun Jun 6 14:20:59 2010 +0200

    BIRNET: improve malloc_aligned to take cache line size into account.
    
    Ensure that no false sharing occurs, by aligning on cache line size if
    possible, and increasing data block size at the beginning and end, so that
    working memory resides in seperate cache lines from everything else.

 birnet/birnetutils.cc |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)
---
diff --git a/birnet/birnetutils.cc b/birnet/birnetutils.cc
index a17f7a8..6a45bda 100644
--- a/birnet/birnetutils.cc
+++ b/birnet/birnetutils.cc
@@ -1378,16 +1378,30 @@ malloc_aligned (gsize	  total_size,
                 gsize	  alignment,
                 guint8	**free_pointer)
 {
-  uint8 *aligned_mem = (uint8*) g_malloc (total_size);
-  *free_pointer = aligned_mem;
-  if (!alignment || !(ptrdiff_t) aligned_mem % alignment)
-    return aligned_mem;
-  g_free (aligned_mem);
-  aligned_mem = (uint8*) g_malloc (total_size + alignment - 1);
-  *free_pointer = aligned_mem;
-  if ((ptrdiff_t) aligned_mem % alignment)
-    aligned_mem += alignment - (ptrdiff_t) aligned_mem % alignment;
-  return aligned_mem;
+  const bool  alignment_power_of_2 = (alignment & (alignment - 1)) == 0;
+  const gsize cache_line_size = 64; // ensure that no false sharing will occur (at begin and end of data)
+
+  if (alignment_power_of_2)
+    {
+      // for power of 2 alignment, we guarantee also cache line alignment
+      alignment = std::max (alignment, cache_line_size);
+
+      uint8 *aligned_mem = (uint8 *) g_malloc (total_size + (alignment - 1) + (cache_line_size - 1));
+      *free_pointer = aligned_mem;
+      if ((ptrdiff_t) aligned_mem % alignment)
+        aligned_mem += alignment - (ptrdiff_t) aligned_mem % alignment;
+      return aligned_mem;
+    }
+  else
+    {
+      uint8 *aligned_mem = (uint8 *) g_malloc (total_size + (alignment - 1) + (cache_line_size - 1) * 2);
+      *free_pointer = aligned_mem;
+      if ((ptrdiff_t) aligned_mem % cache_line_size)
+        aligned_mem += cache_line_size - (ptrdiff_t) aligned_mem % cache_line_size;
+      if ((ptrdiff_t) aligned_mem % alignment)
+        aligned_mem += alignment - (ptrdiff_t) aligned_mem % alignment;
+      return aligned_mem;
+    }
 }
 
 /* --- zintern support --- */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]