Anonymous avatar Anonymous committed 3fc48cf

added cached memory management option, which is disabled since it doesn't seem to make a difference

Comments (0)

Files changed (3)

 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#include <string.h>
 #include "misc.h"
 #ifdef HAVE_MM_MALLOC
 #include <mm_malloc.h>
 #endif
 
-
+/* blocks of memory we like to keep around for later re-use */
+mm_block m4ri_mmc_cache[M4RI_MMC_NBLOCKS];
 
 void m4ri_die(char *errormessage, ...) {
   /*This function prints the error message and raises SIGABRT.*/
   }
 }
 
+
 void *m4ri_mm_calloc( int count, int size ) {
   /* this function calls calloc with the given inputs, 
      but dies with an error message if a NULL is returned */
 #include "config.h"
 #endif
 
+#include <string.h>
+
 /*
  * These define entirely the word width used in the library.
  */
  */
 void m4ri_word_to_str( char *destination, word data, int colon);
 
+/**
+ * \brief Return 1 or 0 uniformly randomly distributed.
+ *
+ * \todo Allow user to provide her own random() function.
+ */
+
+BIT m4ri_coin_flip();
+
 /***** Memory Management *****/
 
 /**
 void m4ri_mm_free(void *condemned);
 
 /**
- * \brief Return 1 or 0 uniformly randomly distributed.
- *
- * \todo Allow user to provide her own random() function.
+ * Number of blocks that are cached.
  */
 
-BIT m4ri_coin_flip();
+#define M4RI_MMC_NBLOCKS 16
+
+/**
+ * Maximal size of blocks stored in cache.
+ */
+
+#ifdef CPU_L2_CACHE
+#define M4RI_MMC_THRESHOLD CPU_L2_CACHE
+#else
+#define M4RI_MMC_THRESHOLD 1024*1024
+#endif
+
+/**
+ * The mmc memory management functions check a cache for re-usable
+ * unused memory before asking the system for it.
+ */
+
+typedef struct _mm_block {
+  /**
+   * Size in bytes of the data.
+   */
+  size_t size;
+
+  /**
+   * Pointer to buffer of data.
+   */
+  void *data;
+
+} mm_block;
+
+extern mm_block m4ri_mmc_cache[M4RI_MMC_NBLOCKS];
+
+/**
+ * Return handle for locale memory management cache.
+ * 
+ * \todo Make thread safe.
+ */
+
+static inline mm_block *m4ri_mmc_handle() {
+  return m4ri_mmc_cache;
+}
+
+/**
+ * Allocate size bytes.
+ *
+ * \param size Number of bytes.
+ */
+
+static inline void *m4ri_mmc_malloc(size_t size) {
+  mm_block *mm = m4ri_mmc_handle();
+  if (size <= M4RI_MMC_THRESHOLD) {
+    size_t i;
+    for (i=0; i<M4RI_MMC_NBLOCKS; i++) {
+      if(mm[i].size == size) {
+        void *ret = mm[i].data;
+        mm[i].data = NULL;
+        mm[i].size = 0;
+        return ret;
+      }
+    }
+  }
+  return m4ri_mm_malloc(size);
+}
+
+/**
+ * Allocate size zeroes bytes.
+ *
+ * \param size Number of bytes.
+ */
+
+static inline void *m4ri_mmc_calloc(size_t size, size_t count) {
+  void *ret = m4ri_mmc_malloc(size*count);
+  memset(ret, 0, count*size);
+  return ret;
+}
+
+/**
+ * Free the data pointed to by condemned of the given size.
+ *
+ * \param condemned Pointer to memory.
+ * \param size Number of bytes.
+ */
+
+static inline void m4ri_mmc_free(void *condemned, size_t size) {
+  mm_block *mm = m4ri_mmc_handle();
+  if (size < M4RI_MMC_THRESHOLD) {
+    size_t i;
+    for(i=0; i<M4RI_MMC_NBLOCKS; i++) {
+      if(mm[i].size == 0) {
+        mm[i].size = size;
+        mm[i].data = condemned;
+        return;
+      }
+    }
+  }
+  m4ri_mm_free(condemned);
+}
+
+/**
+ * Cleans up the cache.
+ */
+
+static inline void m4ri_mmc_cleanup() {
+  mm_block *mm = m4ri_mmc_handle();
+  size_t i;
+  for(i=0; i < M4RI_MMC_NBLOCKS; i++) {
+    if (mm[i].size)
+      m4ri_mm_free(mm[i].data);
+    mm[i].size = 0;
+  }
+}
 
 #endif //MISC_H

src/packedmatrix.c

   newmatrix->ncols=c;
   newmatrix->nrows=r;
   newmatrix->offset = 0;
-  newmatrix->values=(word *)m4ri_mm_calloc( (newmatrix->width)*r, sizeof(word));
+  newmatrix->values=(word *)m4ri_mm_calloc( (newmatrix->width)*r, sizeof(word) );
 
-  newmatrix->rowswap=(size_t *)m4ri_mm_malloc( r * sizeof(size_t));
+  newmatrix->rowswap=(size_t *)m4ri_mm_malloc( r * sizeof(size_t) );
 
   /* Rowswap does not contain the rowswap index i but the correct
    * offset in the values table. Rowswap is exclusively used to access
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.