Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 322
NUMA bindings support for Shm Segments#161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // @nolint instantiates a small cache and runs a quick run of basic operations. | ||
| { | ||
| "cache_config" : { | ||
| "cacheSizeMB" : 512, | ||
| "usePosixShm" : false, | ||
| "cacheDir" : "/tmp/mem-tiers", | ||
| "memoryTiers" : [ | ||
| { | ||
| "ratio": 1, | ||
| "memBindNodes": "0" | ||
| } | ||
| ], | ||
| "poolRebalanceIntervalSec" : 1, | ||
| "moveOnSlabRelease" : false, | ||
| "numPools" : 2, | ||
| "poolSizes" : [0.3, 0.7] | ||
| }, | ||
| "test_config" : { | ||
| "numOps" : 100000, | ||
| "numThreads" : 32, | ||
| "numKeys" : 1000000, | ||
| "keySizeRange" : [1, 8, 64], | ||
| "keySizeRangeProbability" : [0.3, 0.7], | ||
| "valSizeRange" : [1, 32, 10240, 409200], | ||
| "valSizeRangeProbability" : [0.1, 0.2, 0.7], | ||
| "getRatio" : 0.15, | ||
| "setRatio" : 0.8, | ||
| "delRatio" : 0.05, | ||
| "keyPoolDistribution": [0.4, 0.6], | ||
| "opPoolDistribution" : [0.5, 0.5] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -41,6 +41,26 @@ class CacheMonitorFactory { | ||
| virtual std::unique_ptr<CacheMonitor> create(Lru2QAllocator& cache) = 0; | ||
| }; | ||
| // Parse memory tiers configuration from JSON config | ||
| struct MemoryTierConfig : public JSONConfig { | ||
| MemoryTierConfig() {} | ||
| explicit MemoryTierConfig(const folly::dynamic& configJson); | ||
jaesoo-fb marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| // Returns MemoryTierCacheConfig parsed from JSON config | ||
| MemoryTierCacheConfig getMemoryTierCacheConfig() { | ||
jaesoo-fb marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| MemoryTierCacheConfig config = MemoryTierCacheConfig::fromShm(); | ||
| config.setRatio(ratio); | ||
| config.setMemBind(NumaBitMask(memBindNodes)); | ||
| return config; | ||
| } | ||
| // Specifies ratio of this memory tier to other tiers | ||
| size_t ratio{0}; | ||
| // Allocate memory only from specified NUMA nodes | ||
| std::string memBindNodes{""}; | ||
jaesoo-fb marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| }; | ||
| struct CacheConfig : public JSONConfig { | ||
| // by defaullt, lru allocator. can be set to LRU-2Q. | ||
| std::string allocator{"LRU"}; | ||
| @@ -194,6 +214,12 @@ struct CacheConfig : public JSONConfig { | ||
| // Not used when its value is 0. In seconds. | ||
| uint32_t memoryOnlyTTL{0}; | ||
| // Use Posix Shm instead of SysVShm | ||
| bool usePosixShm{false}; | ||
| // Memory tiers configs | ||
| std::vector<MemoryTierCacheConfig> memoryTierConfigs{}; | ||
| // If enabled, we will use the timestamps from the trace file in the ticker | ||
| // so that the cachebench will observe time based on timestamps from the trace | ||
| // instead of the system time. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -16,11 +16,15 @@ | ||
| #include "cachelib/shm/PosixShmSegment.h" | ||
| #include <cstring> | ||
| #include <fcntl.h> | ||
| #include <folly/logging/xlog.h> | ||
| #include <sys/mman.h> | ||
| #include <sys/stat.h> | ||
| #include <sys/types.h> | ||
| #include <numa.h> | ||
| #include <numaif.h> | ||
| #include "cachelib/common/Utils.h" | ||
| @@ -166,6 +170,29 @@ void munmapImpl(void* addr, size_t length) { | ||
| } | ||
| } | ||
| void getMempolicyImpl(int &oldMode, NumaBitMask &memBindNumaNodes) { | ||
| auto nodeMask = memBindNumaNodes.getNativeBitmask(); | ||
| long ret = get_mempolicy(&oldMode, nodeMask->maskp, nodeMask->size, | ||
| nullptr, 0); | ||
| if (ret != 0) { | ||
| util::throwSystemError(errno, folly::sformat("get_mempolicy() failed: {}", | ||
| std::strerror(errno))); | ||
| } | ||
| } | ||
| void setMempolicyImpl(int oldMode, const NumaBitMask &memBindNumaNodes) { | ||
| auto nodeMask = memBindNumaNodes.getNativeBitmask(); | ||
| long ret = set_mempolicy(oldMode, nodeMask->maskp, nodeMask->size); | ||
| if (ret != 0) { | ||
| util::throwSystemError(errno, folly::sformat("set_mempolicy() failed: {}", | ||
| std::strerror(errno))); | ||
| } | ||
| } | ||
| } // namespace detail | ||
| PosixShmSegment::PosixShmSegment(ShmAttachT, | ||
| @@ -312,13 +339,50 @@ void* PosixShmSegment::mapAddress(void* addr) const { | ||
| util::throwSystemError(EINVAL, "Address already mapped"); | ||
| } | ||
| XDCHECK(retAddr == addr || addr == nullptr); | ||
| memBind(addr); | ||
| return retAddr; | ||
| } | ||
| void PosixShmSegment::unMap(void* addr) const { | ||
| detail::munmapImpl(addr, getSize()); | ||
| } | ||
| static void forcePageAllocation(void* addr, size_t size, size_t pageSize) { | ||
| char* startAddr = reinterpret_cast<char*>(addr); | ||
| char* endAddr = startAddr + size; | ||
| for (volatile char* curAddr = startAddr; curAddr < endAddr; curAddr += pageSize) { | ||
| *curAddr = *curAddr; | ||
| } | ||
| } | ||
| void PosixShmSegment::memBind(void* addr) const { | ||
| if (opts_.memBindNumaNodes.empty()) { | ||
| return; | ||
| } | ||
| NumaBitMask oldMemBindNumaNodes; | ||
| int oldMode = 0; | ||
| // mbind() cannot be used because mmap was called with MAP_SHARED flag | ||
| // But we can set memory policy for current thread and force page allocation. | ||
| // The following logic is used: | ||
| // 1. Remember current memory policy for the current thread | ||
| // 2. Set new memory policy as specified by config | ||
| // 3. Force page allocation by touching every page in the segment | ||
| // 4. Restore memory policy | ||
| // Remember current memory policy | ||
| detail::getMempolicyImpl(oldMode, oldMemBindNumaNodes); | ||
| // Set memory bindings | ||
| detail::setMempolicyImpl(MPOL_BIND, opts_.memBindNumaNodes); | ||
| forcePageAllocation(addr, getSize(), detail::getPageSize(opts_.pageSize)); | ||
jaesoo-fb marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| // Restore memory policy for the thread | ||
| detail::setMempolicyImpl(oldMode, oldMemBindNumaNodes); | ||
| } | ||
| std::string PosixShmSegment::createKeyForName( | ||
| const std::string& name) noexcept { | ||
| // ensure that the slash is always there in the head. repetitive | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.