make mempool thread-safe in smp; fix smp performance problem in gemini
authorYanhua Sun <sun51@hopper07.(none)>
Thu, 27 Oct 2011 06:23:27 +0000 (23:23 -0700)
committerYanhua Sun <sun51@hopper07.(none)>
Thu, 27 Oct 2011 06:23:27 +0000 (23:23 -0700)
src/arch/gemini_gni/machine.c
src/arch/util/mempool.c
src/arch/util/mempool.h

index 8412a427b76873a753c4aba48d8b15c57a8c17a7..59e3ef18ba1b325e52c0207066ab1b9c4bfa3626 100644 (file)
@@ -138,8 +138,6 @@ static int  SMSG_MAX_MSG = 1024;
 #define ALIGN64(x)       (size_t)((~63)&((x)+63))
 #define ALIGN4(x)        (size_t)((~3)&((x)+3)) 
 
-static int Mempool_MaxSize = 1024*1024*128;
-
 #define     useDynamicSMSG    0
 //static int useDynamicSMSG   = 1;
 static int useStaticMSGQ = 0;
@@ -394,10 +392,7 @@ static MSG_LIST *buffered_fma_tail = 0;
 #define SET_BITS(a,ind) a = ( a | (1<<(ind )) )
 #define Reset(a,ind) a = ( a & (~(1<<(ind))) )
 
-#if CMK_SMP
-CmiNodeLock     mempoolLock;
-#endif
-static mempool_type  *mempool = NULL;
+CpvDeclare(mempool_type*, mempool);
 
 /* get the upper bound of log 2 */
 int mylog2(int size)
@@ -878,8 +873,6 @@ CmiCommHandle LrtsSendFunc(int destNode, int size, char *msg, int mode)
     return 0;
 }
 
-void LrtsPreCommonInit(int everReturn){}
-
 /* Idle-state related functions: called in non-smp mode */
 void CmiNotifyIdleForGemini(void) {
     AdvanceCommunication();
@@ -1688,6 +1681,14 @@ void free_mempool_block(void *ptr, gni_mem_handle_t mem_hndl)
     free(ptr);
 }
 #endif
+void LrtsPreCommonInit(int everReturn){
+#if USE_LRTS_MEMPOOL
+    CpvInitialize(mempool_type*, mempool);
+    CpvAccess(mempool) = mempool_init(_mempool_size, alloc_mempool_block, free_mempool_block);
+#endif
+}
+
+
 FILE *debugLog = NULL;
 void LrtsInit(int *argc, char ***argv, int *numNodes, int *myNodeID)
 {
@@ -1706,7 +1707,6 @@ void LrtsInit(int *argc, char ***argv, int *numNodes, int *myNodeID)
     //void (*remote_smsg_event_handler)(gni_cq_entry_t *, void *) = &RemoteSmsgEventHandle;
     //void (*remote_bte_event_handler)(gni_cq_entry_t *, void *)  = &RemoteBteEventHandle;
    
-    //Mempool_MaxSize = CmiGetArgFlag(*argv, "+useMemorypoolSize");
     //useDynamicSMSG = CmiGetArgFlag(*argv, "+useDynamicSmsg");
        //useStaticMSGQ = CmiGetArgFlag(*argv, "+useStaticMsgQ");
     
@@ -1806,19 +1806,13 @@ void LrtsInit(int *argc, char ***argv, int *numNodes, int *myNodeID)
 #if     USE_LRTS_MEMPOOL
     CmiGetArgLong(*argv, "+useMemorypoolSize", &_mempool_size);
     if (myrank==0) printf("Charm++> use memorypool size: %1.fMB\n", _mempool_size/1024.0/1024);
-    mempool = mempool_init(_mempool_size, alloc_mempool_block, free_mempool_block);
-    //init_mempool(Mempool_MaxSize);
 #endif
-    //init_mempool(Mempool_MaxSize);
 
     /* init DMA buffer for medium message */
 
     //_init_DMA_buffer();
     
     free(MPID_UGNI_AllAddr);
-#if CMK_SMP
-    mempoolLock = CmiCreateLock();
-#endif
     sendRdmaBuf = PCQueueCreate(); 
 }
 
@@ -1839,13 +1833,7 @@ void* LrtsAlloc(int n_bytes, int header)
         CmiAssert(header <= ALIGNBUF);
 #if     USE_LRTS_MEMPOOL
         n_bytes = ALIGN64(n_bytes);
-#if     CMK_SMP
-        CmiLock(mempoolLock);
-#endif
-        char *res = mempool_malloc(mempool, ALIGNBUF+n_bytes, 1);
-#if     CMK_SMP
-        CmiUnlock(mempoolLock);
-#endif
+        char *res = mempool_malloc(CpvAccess(mempool), ALIGNBUF+n_bytes, 1);
         ptr = res - sizeof(mempool_header) + ALIGNBUF - header;
 #else
         n_bytes = ALIGN4(n_bytes);           /* make sure size if 4 aligned */
@@ -1870,12 +1858,11 @@ void  LrtsFree(void *msg)
         printf("[PE:%d] Free lrts for bytes=%d, ptr=%p\n", CmiMyPe(), size, (char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF);
 #endif
 #if     USE_LRTS_MEMPOOL
-#if     CMK_SMP
-        CmiLock(mempoolLock);
-#endif
-        mempool_free(mempool, (char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF + sizeof(mempool_header));
-#if     CMK_SMP
-        CmiUnlock(mempoolLock);
+#if CMK_SMP
+
+        mempool_free_thread((char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF + sizeof(mempool_header));
+#else
+        mempool_free(CpvAccess(mempool), (char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF + sizeof(mempool_header));
 #endif
 #else
         free((char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF);
@@ -1890,8 +1877,7 @@ void LrtsExit()
 {
     /* free memory ? */
 #if     USE_LRTS_MEMPOOL
-    if (CmiMyRank() == 0)
-        mempool_destroy(mempool);
+    mempool_destroy(CpvAccess(mempool));
 #endif
     PMI_Finalize();
     exit(0);
@@ -1899,6 +1885,7 @@ void LrtsExit()
 
 void LrtsDrainResources()
 {
+    if(mysize == 1) return;
     while (!SendBufferMsg()) {
         PumpNetworkSmsg();
         PumpNetworkRdmaMsgs();
index bf419330c97301b4fdc80682623a08c5a76b6836..58d0628b291d203822e3398e7fecfa244cbac693 100644 (file)
@@ -35,6 +35,9 @@ mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool
     mptr = (mempool_type*)pool;
     mptr->newblockfn = allocfn;
     mptr->freeblockfn = freefn;
+#if CMK_SMP
+    mptr->mempoolLock = CmiCreateLock();
+#endif
     mptr->mempools_head.mempool_ptr = pool;
     mptr->mempools_head.mem_hndl = mem_hndl;
     mptr->mempools_head.size = pool_size;
@@ -74,6 +77,10 @@ void*  mempool_malloc(mempool_type *mptr, int size, int expand)
 {
     int     bestfit_size = MAX_INT; //most close size 
     size_t    *freelist_head = &mptr->freelist_head;
+    
+#if CMK_SMP
+    CmiLock(mptr->mempoolLock);
+#endif
     mempool_header    *freelist_head_ptr = mptr->freelist_head?(mempool_header*)((char*)mptr+mptr->freelist_head):NULL;
     mempool_header    *current = freelist_head_ptr;
     mempool_header    *previous = NULL;
@@ -201,9 +208,28 @@ void*  mempool_malloc(mempool_type *mptr, int size, int expand)
 printf("[%d] freelist_head in malloc  offset:%d free_head: %ld %ld %d %d\n", myrank, (char*)bestfit-(char*)mptr, *freelist_head, ((mempool_header*)((char*)mptr+*freelist_head))->next_free, bestfit_size, size);
 #endif
     CmiAssert(*freelist_head >= 0);
+#if CMK_SMP
+    CmiUnlock(mptr->mempoolLock);
+#endif
+#if CMK_SMP
+    ((mempool_header *)bestfit)->pool_addr = mptr;
+#endif
     return (char*)bestfit + sizeof(mempool_header);
 }
 
+#if CMK_SMP
+void mempool_free_thread( void *ptr_free)
+{
+    mempool_header *to_free;
+    mempool_type *mptr;
+
+    to_free = (mempool_header *)((char*)ptr_free - sizeof(mempool_header));
+    mptr = (mempool_type*)(to_free->pool_addr); 
+    CmiLock(mptr->mempoolLock);
+    mempool_free(mptr,  ptr_free); 
+    CmiUnlock(mptr->mempoolLock);
+}
+#endif
 //sorted free_list and merge it if it become continous 
 void mempool_free(mempool_type *mptr, void *ptr_free)
 {
index 76cf1e52b4a963eba2ec811ccd98e6e1562669e4..dd1955dbd3103d3d90054ead5fca1eda90785f20 100644 (file)
@@ -29,6 +29,9 @@ typedef struct mempool_header
   int size;
   mem_handle_t  mem_hndl;
   size_t            next_free;
+#if CMK_SMP
+  void*             pool_addr;
+#endif
 } mempool_header;
 
 typedef void * (* mempool_newblockfn)(size_t *size, mem_handle_t *mem_hndl, int expand_flag);
@@ -42,13 +45,18 @@ typedef struct mempool_type
   mempool_freeblock      freeblockfn;
   size_t          freelist_head;
   size_t          memblock_tail;
+#if CMK_SMP
+  CmiNodeLock     mempoolLock;
+#endif
 } mempool_type;
 
 mempool_type *mempool_init(size_t pool_size, mempool_newblockfn newfn, mempool_freeblock freefn);
 void  mempool_destroy(mempool_type *mptr);
 void*  mempool_malloc(mempool_type *mptr, int size, int expand);
 void mempool_free(mempool_type *mptr, void *ptr_free);
-
+#if CMK_SMP
+void mempool_free_thread(void *ptr_free);
+#endif
 #if defined(__cplusplus)
 extern "C" {
 #endif