CMS 3D CMS Logo

MallocOpts.cc

Go to the documentation of this file.
00001 
00002 
00003 // -*- C++ -*-
00004 //
00005 // Package:     Utilities
00006 // Class  :     MallocOpts
00007 // 
00008 // Original Author:  Jim Kowalkowski
00009 // $Id: MallocOpts.cc,v 1.6 2008/01/18 20:10:32 wmtan Exp $
00010 //
00011 // ------------------ resetting malloc options -----------------------
00012 
00013 
00014 #include "FWCore/Utilities/interface/MallocOpts.h"
00015 
00016 #include <malloc.h>
00017 #include <sstream>
00018 #include <iostream>
00019 
00020 namespace edm
00021 {
00022 
00023   std::ostream& operator<<(std::ostream& ost,const MallocOpts& opts)
00024   {
00025     ost << "mmap_max=" << opts.mmap_max_
00026         << " trim_threshold=" << opts.trim_thr_
00027         << " top_padding=" << opts.top_pad_
00028         << " mmap_threshold=" << opts.mmap_thr_;
00029     return ost;
00030   }
00031 
00032   namespace 
00033   {
00034     typedef enum { UNKNOWN_CPU=0, AMD_CPU=1, INTEL_CPU=2 } cpu_type;
00035   
00036     cpu_type get_cpu_type()
00037     {
00038       // issue: these need to be static.  The asm instruction combined
00039       // with optimization on the 64 bit platform moves the stack data
00040       // member around in such a way that the =m directive misses the
00041       // the location.   Of course this means that this routine is not
00042       // multithread safe.
00043       static volatile int op=0,a;
00044       static volatile int ans[4];
00045 
00046 // Still some problem on x86_64, so only i386 for now    
00047 #if defined(__x86_64__)
00048 
00049       __asm__ __volatile__ ("pushq %%rdx;\
00050  pushq %%rcx;                            \
00051  pushq %%rsi;                            \
00052  pushq %%rbx;                            \
00053  cpuid;                                  \
00054  movq  %%rbx,%%rsi;                      \
00055  popq  %%rbx;                            \
00056  movl  %%ecx,%0;                         \
00057  movl  %%edx,%1;                         \
00058  movl  %%esi,%2;                         \
00059  movl  %%eax,%3;                         \
00060  popq  %%rsi;                            \
00061  popq  %%rcx;                            \
00062  popq  %%rdx;"
00063                             : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00064                             : "a"(op)
00065                             );
00066 
00067 #elif defined(__i386__)
00068 
00069 
00070       __asm__ __volatile__ ("pushl %%edx;\
00071  pushl %%ecx;                            \
00072  pushl %%esi;                            \
00073  pushl %%ebx;                            \
00074  cpuid;                                  \
00075  movl  %%ebx,%%esi;                      \
00076  popl  %%ebx;                            \
00077  movl  %%ecx,%0;                         \
00078  movl  %%edx,%1;                         \
00079  movl  %%esi,%2;                         \
00080  movl  %%eax,%3;                         \
00081  popl  %%esi;                            \
00082  popl  %%ecx;                            \
00083  popl  %%edx;"
00084                             : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00085                             : "a"(op)
00086                             );
00087 
00088     
00089 #else
00090       const char* unknown_str = "Unknown";
00091       // int unknown_sz = strlen(unknown_str);
00092       strcpy((char*)&ans[0],unknown_str);
00093 #endif
00094       
00095       const char* amd_str = "AuthenticAMD";
00096       int amd_sz = strlen(amd_str);
00097       const char* intel_str = "GenuineIntel";
00098       int intel_sz = strlen(intel_str);
00099     
00100       char* str = (char*)&ans[0];
00101       ans[3]=0;
00102 
00103       return strncmp(str,amd_str,amd_sz)==0?AMD_CPU:
00104         strncmp(str,intel_str,intel_sz)==0?INTEL_CPU:UNKNOWN_CPU;
00105     }
00106 
00107     // values determined experimentally for each architecture
00108     const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
00109     const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
00110 
00111   }
00112 
00113 
00114   bool MallocOptionSetter::retrieveFromCpuType()
00115   {
00116     bool rc=true;
00117 
00118     switch(get_cpu_type())
00119       {
00120       case AMD_CPU:
00121         {
00122           values_ = amd_opts;
00123           changed_=true;
00124           break;
00125         }
00126       case INTEL_CPU:
00127         {
00128           values_ = intel_opts;
00129           changed_=true;
00130           break;
00131         }
00132       case UNKNOWN_CPU:
00133       default:
00134         rc=false;
00135       }
00136 
00137     return rc;
00138   }
00139 
00140   MallocOptionSetter::MallocOptionSetter():
00141     changed_(false)
00142   {
00143     if(retrieveFromEnv() || retrieveFromCpuType())
00144       {
00145         adjustMallocParams();
00146         if(hasErrors())
00147           {
00148             std::cerr << "ERROR: Reset of malloc options has fails:\n"
00149                       << error_message_ << "\n";
00150           }
00151       }
00152   }
00153 
00154   void MallocOptionSetter::adjustMallocParams()
00155   {
00156     if(changed_==false) return; // only adjust if they changed
00157     error_message_.clear();
00158     changed_ = false;
00159 
00160     if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
00161       error_message_ += "Could not set M_MMAP_MAX\n"; 
00162     if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
00163       error_message_ += "Could not set M_TRIM_THRESHOLD\n"; 
00164     if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
00165       error_message_ += "ERROR: Could not set M_TOP_PAD\n";
00166     if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
00167       error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
00168   }
00169 
00170   bool MallocOptionSetter::retrieveFromEnv()
00171   {
00172     const char* par = getenv("CMSRUN_MALLOC_RESET");
00173     if(par==0) return false; // leave quickly here
00174     std::string spar(par);
00175     bool rc = false;
00176       
00177     // CMSRUN_MALLOC_RESET = "mmap_max trim_thres top_pad mmap_thres"
00178       
00179     if(spar.size()>1)
00180       {
00181         std::istringstream ist(spar);
00182         ist >> values_.mmap_max_ >> values_.trim_thr_
00183             >> values_.top_pad_ >> values_.mmap_thr_;
00184 
00185         if(ist.bad())
00186           {
00187             std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
00188                       << spar << "\n"
00189                       << "format is: "
00190                       << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
00191           }
00192         else
00193           {
00194             std::cout << "MALLOC_OPTIONS> Reset options: "
00195                       << "CMSRUN_MALLOC_RESET=" << par << "\n";
00196           }
00197         rc=true;
00198         changed_=true;
00199       }
00200 
00201     return rc;
00202   }
00203 
00204   MallocOptionSetter global_malloc_options;
00205 
00206   MallocOptionSetter& getGlobalOptionSetter()
00207   {
00208     return global_malloc_options;
00209   }
00210 
00211 
00212   // ----------------------------------------------------------------
00213 }

Generated on Tue Jun 9 17:36:47 2009 for CMSSW by  doxygen 1.5.4