-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[VTA][TSIM] Introduce Virtual Memory for TSIM Driver #3686
Merged
Merged
Changes from 11 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
f4fa007
initial virtual memory;
liangfu 74a5426
initial integration;
liangfu 2efdc9f
include the header file in cmake;
liangfu bdc9814
implement allocation with virtual to logical address mapping;
liangfu 78e08db
Merge branch 'master' into virtual_memory
liangfu 296abbb
virtual memory for tsim_driver;
liangfu 4a7674b
implement the missing memory release function;
liangfu 91d93c9
readability improvement;
liangfu 477633c
readability improvement;
liangfu ed97480
address review comments;
liangfu 832a598
improved robustness in virtual memory allocation;
liangfu b0a185a
remove VTA_TSIM_USE_VIRTUAL_MEMORY macro and use virtual memory for t…
liangfu 843b27b
Merge branch 'master' into virtual_memory
liangfu 98a9496
link tvm against vta library;
liangfu 7fdf943
Merge branch 'master' into virtual_memory
liangfu 70a8f26
merge with master
liangfu d8ce8b6
build virtual memory system without linking tvm against vta;
liangfu 0cdaf42
minor change;
liangfu 586fd89
reuse VTA_PAGE_BYTES;
liangfu 9064fb9
using DRAM class from sim_driver as VirtualMemoryManager;
liangfu 9dab853
satisfy linter;
liangfu 3ea1354
add comments in code;
liangfu 7f6fd85
Merge branch 'master' into virtual_memory
liangfu 7a1774a
undo changes to Makefile
liangfu 676a998
undo changes to Makefile
liangfu 17814ce
retrigger ci;
liangfu 4c0f0f9
Merge branch 'virtual_memory' of github.com:liangfu/tvm into virtual_…
liangfu c223923
retrigger ci;
liangfu 1617787
directly call into VirtualMemoryManager::Global()
liangfu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
#include "virtual_memory.h" | ||
|
||
#include <dmlc/logging.h> | ||
#include <cstdint> | ||
#include <cstdlib> | ||
#include <cstring> | ||
#include <list> | ||
#include <utility> | ||
#include <iterator> | ||
#include <unordered_map> | ||
|
||
/*! page size of virtual address */ | ||
#ifndef VTA_TSIM_VM_PAGE_SIZE | ||
#define VTA_TSIM_VM_PAGE_SIZE (4096) | ||
#endif // VTA_TSIM_VM_PAGE_SIZE | ||
|
||
/*! starting point of the virtual address system */ | ||
#ifndef VTA_TSIM_VM_ADDR_BEGIN | ||
#define VTA_TSIM_VM_ADDR_BEGIN (0x40000000) | ||
#endif // VTA_TSIM_VM_ADDR_BEGIN | ||
|
||
namespace vta { | ||
namespace tsim { | ||
liangfu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
static const uint64_t kPageSize = VTA_TSIM_VM_PAGE_SIZE; | ||
static const uint64_t kVirtualMemoryOffset = VTA_TSIM_VM_ADDR_BEGIN; | ||
|
||
class VirtualMemoryManager { | ||
public: | ||
/*! \brief allocate virtual memory for given size */ | ||
void * Allocate(uint64_t sz) { | ||
uint64_t size = ((sz + kPageSize - 1) / kPageSize) * kPageSize; | ||
void * ptr = malloc(size); | ||
size_t laddr = reinterpret_cast<size_t>(ptr); | ||
// search for available virtual memory space | ||
uint64_t vaddr = kVirtualMemoryOffset; | ||
auto it = page_table_.end(); | ||
if (page_table_.size() > 0) { | ||
for (it = page_table_.begin(); it != page_table_.end(); it++) { | ||
if (it == page_table_.begin()) { continue; } | ||
if (((*it).first - (*std::prev(it)).second) > size) { | ||
vaddr = (*it).second; | ||
break; | ||
} | ||
} | ||
if (it == page_table_.end()) { | ||
vaddr = (*std::prev(it)).second; | ||
} | ||
} | ||
page_table_.insert(it, std::make_pair(vaddr, vaddr + size)); | ||
tlb_[vaddr] = laddr; | ||
// save tlb to file in order to be accessed externally. | ||
FILE * fout = fopen(VTA_VMEM_PAGEFILE, "wb"); | ||
CHECK(fout); | ||
if (fout) { | ||
uint32_t tlb_size = sizeof(uint64_t)*3*tlb_.size(); | ||
uint32_t tlb_cnt = 0; | ||
uint64_t * tlb = new uint64_t[3*tlb_.size()]; | ||
for (auto iter = tlb_.begin(); iter != tlb_.end(); iter++, tlb_cnt++) { | ||
tlb[tlb_cnt * 3] = (*iter).first; | ||
uint64_t vend = 0; | ||
for (auto iter_in = page_table_.begin(); iter_in != page_table_.end(); iter_in++) { | ||
if ((*iter_in).first == (*iter).first) { vend = (*iter_in).second; break; } | ||
} | ||
tlb[tlb_cnt * 3 + 1] = vend; | ||
tlb[tlb_cnt * 3 + 2] = (*iter).second; | ||
} | ||
fwrite(tlb, tlb_size, 1, fout); | ||
fflush(fout); | ||
fclose(fout); | ||
} | ||
// return virtual address | ||
return reinterpret_cast<void*>(vaddr); | ||
} | ||
|
||
/*! \brief release virtual memory for pointer */ | ||
void Release(void * ptr) { | ||
uint64_t src = reinterpret_cast<uint64_t>(ptr); | ||
auto it = page_table_.begin(); | ||
for (; it != page_table_.end(); it++) { | ||
if (((*it).first <= src) && ((*it).second > src)) { break; } | ||
} | ||
CHECK(it != page_table_.end()); | ||
uint64_t * laddr = reinterpret_cast<uint64_t*>(tlb_[(*it).first]); | ||
delete [] laddr; | ||
page_table_.erase(it); | ||
tlb_.erase((*it).first); | ||
} | ||
|
||
/*! \brief copy virtual memory from host */ | ||
void MemCopyFromHost(void * dstptr, const void * src, uint64_t size) { | ||
// get logical address from virtual address | ||
size_t dst = reinterpret_cast<size_t>(dstptr); | ||
auto it = page_table_.begin(); | ||
for (; it != page_table_.end(); it++) { | ||
if (((*it).first <= dst) && ((*it).second > dst)) { break; } | ||
} | ||
CHECK(it != page_table_.end()); | ||
size_t offset = dst - (*it).first; | ||
char * laddr = reinterpret_cast<char*>(tlb_[(*it).first]); | ||
// copy content from src to logic address | ||
memcpy(laddr + offset, src, size); | ||
} | ||
|
||
/*! \brief copy virtual memory to host */ | ||
void MemCopyToHost(void * dst, const void * srcptr, uint64_t size) { | ||
// get logical address from virtual address | ||
size_t src = reinterpret_cast<size_t>(srcptr); | ||
auto it = page_table_.begin(); | ||
for (; it != page_table_.end(); it++) { | ||
if (((*it).first <= src) && ((*it).second > src)) { break; } | ||
} | ||
CHECK(it != page_table_.end()); | ||
size_t offset = src - (*it).first; | ||
char * laddr = reinterpret_cast<char*>(tlb_[(*it).first]); | ||
// copy content from logic address to dst | ||
memcpy(dst, laddr + offset, size); | ||
} | ||
|
||
/*! \brief get logical address from virtual memory */ | ||
void * GetLogicalAddr(uint64_t src) { | ||
if (src == 0) { return 0; } | ||
auto it = page_table_.begin(); | ||
for (; it != page_table_.end(); it++) { | ||
if (((*it).first <= src) && ((*it).second > src)) { break; } | ||
} | ||
CHECK(it != page_table_.end()); | ||
return reinterpret_cast<void*>(tlb_[(*it).first]); | ||
} | ||
|
||
/*! \brief get global handler of the instance */ | ||
static VirtualMemoryManager* Global() { | ||
static VirtualMemoryManager inst; | ||
return &inst; | ||
} | ||
|
||
private: | ||
/*! \brief page table */ | ||
std::list<std::pair<uint64_t, uint64_t> > page_table_; | ||
/*! \brief translation lookaside buffer */ | ||
std::unordered_map<uint64_t, size_t> tlb_; | ||
}; | ||
|
||
} // namespace tsim | ||
} // namespace vta | ||
|
||
|
||
void * vmalloc(uint64_t size) { | ||
return vta::tsim::VirtualMemoryManager::Global()->Allocate(size); | ||
} | ||
|
||
void vfree(void * ptr) { | ||
vta::tsim::VirtualMemoryManager::Global()->Release(ptr); | ||
} | ||
|
||
void vmemcpy(void * dst, const void * src, uint64_t size, VMemCopyType dir) { | ||
auto * mgr = vta::tsim::VirtualMemoryManager::Global(); | ||
if (kVirtualMemCopyFromHost == dir) { | ||
mgr->MemCopyFromHost(dst, src, size); | ||
} else { | ||
mgr->MemCopyToHost(dst, src, size); | ||
} | ||
} | ||
|
||
void * vmem_get_log_addr(uint64_t vaddr) { | ||
return vta::tsim::VirtualMemoryManager::Global()->GetLogicalAddr(vaddr); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we going to leave this parameter turned on by default? what are the pros/cons to leaving this macro to be user-defined (with the idea that we're trying to minimize ifdefs in our code)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advantage
Disadvantage
Otherwise, I think it's safe to enable virtual memory for
tsim_driver
by default.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clear explanation. I'd opt towards leaving it on by default, at the detriment to Windows users, but others can chime in @tqchen @vegaluisjose