32 #include <sys/sysctl.h>
33 #include <sys/types.h>
36 #include <boost/filesystem.hpp>
44 bool g_enable_tiered_cpu_mem{
false};
49 namespace Data_Namespace {
53 std::unique_ptr<CudaMgr_Namespace::CudaMgr> cudaMgr,
55 const size_t reservedGpuMem,
56 const size_t numReaderThreads,
58 : cudaMgr_{std::move(cudaMgr)}
61 , reservedGpuMem_{reservedGpuMem} {
66 LOG(
ERROR) <<
"CudaMgr instance is invalid, falling back to CPU-only mode.";
79 populateMgrs(system_parameters, numReaderThreads, cache_config);
80 createTopLevelMetadata();
85 for (
int level = numLevels - 1; level >= 0; --level) {
86 for (
size_t device = 0; device <
bufferMgrs_[level].size(); device++) {
108 usage.
free = mi[
"MemAvailable"];
109 usage.
total = mi[
"MemTotal"];
116 int64_t resident = 0;
119 std::ifstream fstatm(
"/proc/self/statm");
120 fstatm >> size >> resident >> shared;
124 sysconf(_SC_PAGE_SIZE);
126 usage.
resident = resident * page_size;
127 usage.
vtotal = size * page_size;
128 usage.
regular = (resident - shared) * page_size;
129 usage.
shared = shared * page_size;
152 size_t physical_memory;
157 length =
sizeof(size_t);
158 sysctl(mib, 2, &physical_memory, &length, NULL, 0);
159 return physical_memory;
160 #elif defined(_MSC_VER)
161 MEMORYSTATUSEX status;
162 status.dwLength =
sizeof(status);
163 GlobalMemoryStatusEx(&status);
164 return status.ullTotalPhys;
166 long pages = sysconf(_SC_PHYS_PAGES);
167 long page_size = sysconf(_SC_PAGE_SIZE);
168 return pages * page_size;
173 size_t total_cpu_size,
174 size_t minCpuSlabSize,
175 size_t maxCpuSlabSize,
178 #ifdef ENABLE_MEMKIND
179 if (g_enable_tiered_cpu_mem) {
203 const size_t num_reader_threads,
206 for (
int level = numLevels - 1; level >= 0; --level) {
207 for (
size_t device = 0; device <
bufferMgrs_[level].size(); device++) {
212 populateMgrs(sys_params, num_reader_threads, cache_config);
217 const size_t userSpecifiedNumReaderThreads,
225 size_t page_size{512};
227 if (cpuBufferSize == 0) {
229 VLOG(1) <<
"Detected " << (float)total_system_memory / (1024 * 1024)
230 <<
"M of total system memory.";
231 cpuBufferSize = total_system_memory *
234 size_t minCpuSlabSize = std::min(system_parameters.
min_cpu_slab_size, cpuBufferSize);
235 minCpuSlabSize = (minCpuSlabSize / page_size) * page_size;
236 size_t maxCpuSlabSize = std::min(system_parameters.
max_cpu_slab_size, cpuBufferSize);
237 maxCpuSlabSize = (maxCpuSlabSize / page_size) * page_size;
238 LOG(
INFO) <<
"Min CPU Slab Size is " << (float)minCpuSlabSize / (1024 * 1024) <<
"MB";
239 LOG(
INFO) <<
"Max CPU Slab Size is " << (float)maxCpuSlabSize / (1024 * 1024) <<
"MB";
240 LOG(
INFO) <<
"Max memory pool size for CPU is " << (float)cpuBufferSize / (1024 * 1024)
243 size_t total_cpu_size = 0;
245 #ifdef ENABLE_MEMKIND
248 if (g_enable_tiered_cpu_mem) {
250 LOG(
INFO) <<
"Max memory pool size for PMEM is " << (float)
g_pmem_size / (1024 * 1024)
253 for (
auto cpu_tier_size : cpu_tier_sizes) {
254 total_cpu_size += cpu_tier_size;
258 total_cpu_size = cpuBufferSize;
263 <<
"MB includes render buffer allocation";
266 0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);
269 int numGpus =
cudaMgr_->getDeviceCount();
270 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
271 size_t gpuMaxMemSize =
275 size_t minGpuSlabSize =
277 minGpuSlabSize = (minGpuSlabSize / page_size) * page_size;
278 size_t maxGpuSlabSize =
280 maxGpuSlabSize = (maxGpuSlabSize / page_size) * page_size;
281 LOG(
INFO) <<
"Min GPU Slab size for GPU " << gpuNum <<
" is "
282 << (float)minGpuSlabSize / (1024 * 1024) <<
"MB";
283 LOG(
INFO) <<
"Max GPU Slab size for GPU " << gpuNum <<
" is "
284 << (float)maxGpuSlabSize / (1024 * 1024) <<
"MB";
285 LOG(
INFO) <<
"Max memory pool size for GPU " << gpuNum <<
" is "
286 << (float)gpuMaxMemSize / (1024 * 1024) <<
"MB";
298 0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);
308 boost::filesystem::path path(mapdDataPath);
309 if (boost::filesystem::exists(path)) {
310 if (!boost::filesystem::is_directory(path)) {
312 "\" to convert DB is not a directory.";
316 "\" to convert DB does not exist.";
323 LOG(
INFO) <<
"Database conversion started.";
330 LOG(
INFO) <<
"Database conversion completed.";
343 auto fm_top = gfm->getFileMgr(chunkKey);
344 if (dynamic_cast<File_Namespace::FileMgr*>(fm_top)) {
356 std::vector<MemoryInfo> mem_info;
370 for (
size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
371 for (
auto segment : slab_segments[slab_num]) {
376 md.
touch = segment.last_touched;
379 md.
chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
383 mem_info.push_back(mi);
385 int numGpus =
cudaMgr_->getDeviceCount();
386 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
399 for (
size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
400 for (
auto segment : slab_segments[slab_num]) {
405 md.
touch = segment.last_touched;
407 md.
chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
412 mem_info.push_back(mi);
423 int numGpus =
cudaMgr_->getDeviceCount();
424 std::ostringstream tss;
425 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
426 tss <<
bufferMgrs_[memLevel][gpuNum]->printSlabs();
440 int numGpus =
cudaMgr_->getDeviceCount();
441 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
442 LOG(
INFO) <<
"clear slabs on gpu " << gpuNum;
443 auto buffer_mgr_for_gpu =
445 CHECK(buffer_mgr_for_gpu);
446 buffer_mgr_for_gpu->clearSlabs();
449 LOG(
WARNING) <<
"Unable to clear GPU memory: No GPUs detected";
452 auto buffer_mgr_for_cpu =
454 CHECK(buffer_mgr_for_cpu);
455 buffer_mgr_for_cpu->clearSlabs();
461 const int deviceId) {
463 return bufferMgrs_[memLevel][deviceId]->isBufferOnDevice(key);
469 bufferMgrs_[0][0]->getChunkMetadataVecForKeyPrefix(chunkMetadataVec, keyPrefix);
475 const size_t page_size) {
477 int level =
static_cast<int>(memoryLevel);
478 return bufferMgrs_[level][deviceId]->createBuffer(key, page_size);
484 const size_t numBytes) {
486 const auto level =
static_cast<size_t>(memoryLevel);
489 return bufferMgrs_[level][deviceId]->getBuffer(key, numBytes);
496 for (
int level = numLevels - 1; level >= 0; --level) {
497 for (
int device = 0; device <
levelSizes_[level]; ++device) {
498 bufferMgrs_[level][device]->deleteBuffersWithPrefix(keyPrefix);
511 for (
int device = 0; device <
levelSizes_[memLevel]; ++device) {
512 bufferMgrs_[memLevel][device]->deleteBuffersWithPrefix(keyPrefix);
518 const size_t numBytes) {
520 const auto level =
static_cast<int>(memoryLevel);
522 return bufferMgrs_[level][deviceId]->alloc(numBytes);
527 int level =
static_cast<int>(buffer->
getType());
551 for (
auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
552 (*deviceIt)->checkpoint(db_id, tb_id);
563 for (
int device_id = 0; device_id <
levelSizes_[memory_level]; device_id++) {
564 bufferMgrs_[memory_level][device_id]->checkpoint(db_id, table_id);
574 for (
auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
575 (*deviceIt)->checkpoint();
582 bufferMgrs_[0][0]->removeTableRelatedDS(db_id, tb_id);
589 gfm->setTableEpoch(db_id, tb_id, start_epoch);
596 return gfm->getTableEpoch(db_id, tb_id);
603 gfm->resetTableEpochFloor(db_id, tb_id);
610 CHECK(global_file_mgr);
611 return global_file_mgr;
622 os <<
" \"name\": \"CPU Memory Info\",";
623 os <<
" \"TotalMB\": " << mem_info.
total / (1024. * 1024.) <<
",";
624 os <<
" \"FreeMB\": " << mem_info.
free / (1024. * 1024.) <<
",";
625 os <<
" \"ProcessMB\": " << mem_info.
resident / (1024. * 1024.) <<
",";
626 os <<
" \"VirtualMB\": " << mem_info.
vtotal / (1024. * 1024.) <<
",";
627 os <<
" \"ProcessPlusSwapMB\": " << mem_info.
regular / (1024. * 1024.) <<
",";
628 os <<
" \"ProcessSharedMB\": " << mem_info.
shared / (1024. * 1024.) <<
",";
629 os <<
" \"FragmentationPercent\": " << mem_info.
frag;
size_t getAllocated() override
std::mutex buffer_access_mutex_
std::vector< int > ChunkKey
const std::string kDataDirectoryName
void resetPersistentStorage(const File_Namespace::DiskCacheConfig &cache_config, const size_t num_reader_threads, const SystemParameters &sys_params)
std::vector< MemoryData > nodeMemoryData
Buffer_Namespace::MemStatus memStatus
size_t getMaxSize() override
std::vector< std::vector< AbstractBufferMgr * > > bufferMgrs_
This file includes the class specification for the FILE manager (FileMgr), and related data structure...
std::vector< int > levelSizes_
std::ostream & operator<<(std::ostream &os, const DataMgr::SystemMemoryUsage &mem_info)
SystemMemoryUsage getSystemMemoryUsage() const
size_t cpu_buffer_mem_bytes
PersistentStorageMgr * getPersistentStorageMgr() const
virtual int8_t * getMemoryPtr()=0
virtual MemoryLevel getType() const =0
void clearMemory(const MemoryLevel memLevel)
std::vector< MemoryInfo > getMemoryInfoUnlocked(const MemoryLevel memLevel) const
void resetTableEpochFloor(const int32_t db_id, const int32_t tb_id)
std::string dumpLevel(const MemoryLevel memLevel)
void convertDB(const std::string basePath)
constexpr size_t numCpuTiers
static size_t getTotalSystemMemory()
Note(s): Forbid Copying Idiom 4.1.
size_t getTableEpoch(const int db_id, const int tb_id)
Buffer_Namespace::GpuCudaBufferMgr * getGpuBufferMgr(int32_t device_id) const
std::shared_ptr< ForeignStorageInterface > getForeignStorageInterface() const
void createTopLevelMetadata() const
bool isAllocationCapped() override
std::unique_ptr< CudaMgr_Namespace::CudaMgr > cudaMgr_
void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector &chunkMetadataVec, const ChunkKey &keyPrefix)
void populateMgrs(const SystemParameters &system_parameters, const size_t userSpecifiedNumReaderThreads, const File_Namespace::DiskCacheConfig &cache_config)
An AbstractBuffer is a unit of data management for a data manager.
virtual void write(int8_t *src, const size_t num_bytes, const size_t offset=0, const MemoryLevel src_buffer_type=CPU_LEVEL, const int src_device_id=-1)=0
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Parse /proc/meminfo into key/value pairs.
void deleteChunksWithPrefix(const ChunkKey &keyPrefix)
const std::vector< BufferList > & getSlabSegments()
bool isBufferOnDevice(const ChunkKey &key, const MemoryLevel memLevel, const int deviceId)
AbstractBuffer * getChunkBuffer(const ChunkKey &key, const MemoryLevel memoryLevel, const int deviceId=0, const size_t numBytes=0)
std::vector< MemoryInfo > getMemoryInfo(const MemoryLevel memLevel) const
void removeTableRelatedDS(const int db_id, const int tb_id)
DataMgr(const std::string &dataDir, const SystemParameters &system_parameters, std::unique_ptr< CudaMgr_Namespace::CudaMgr > cudaMgr, const bool useGpus, const size_t reservedGpuMem=(1<< 27), const size_t numReaderThreads=0, const File_Namespace::DiskCacheConfig cacheConfig=File_Namespace::DiskCacheConfig())
Buffer_Namespace::CpuBufferMgr * getCpuBufferMgr() const
void copy(AbstractBuffer *destBuffer, AbstractBuffer *srcBuffer)
size_t gpu_buffer_mem_bytes
std::vector< int32_t > chunk_key
AbstractBuffer * createChunkBuffer(const ChunkKey &key, const MemoryLevel memoryLevel, const int deviceId=0, const size_t page_size=0)
Allocate GPU memory using GpuBuffers via DataMgr.
void free(AbstractBuffer *buffer)
auto getFragmentationPercent()
void allocateCpuBufferMgr(int32_t device_id, size_t total_cpu_size, size_t minCpuSlabSize, size_t maxCpuSlabSize, size_t page_size, const std::vector< size_t > &cpu_tier_sizes)
std::vector< size_t > CpuTierSizeVector
Parse /proc/buddyinfo into a Fragmentation health score.
void setTableEpoch(const int db_id, const int tb_id, const int start_epoch)
AbstractBuffer * alloc(const MemoryLevel memoryLevel, const int deviceId, const size_t numBytes)