This commit is contained in:
blueloveTH 2023-04-08 15:48:47 +08:00
parent e03ce955fc
commit ef3e172fbd
7 changed files with 32 additions and 26 deletions

View File

@ -4,3 +4,5 @@ def fib(n):
return fib(n-1) + fib(n-2)
assert fib(32) == 2178309
# 7049155 calls

5
run_profile.sh Normal file
View File

@ -0,0 +1,5 @@
# THIS SCRIPT IS NOT WORKING
clang++ -pg -O2 -std=c++17 -fno-rtti -stdlib=libc++ -Wall -o pocketpy src/main.cpp
time ./pocketpy benchmarks/fib.py
gprof pocketpy gmon.out > gprof.txt
rm gmon.out

View File

@ -41,8 +41,6 @@
#define DEBUG_NO_AUTO_GC 0
#define DEBUG_GC_STATS 0
#define DEBUG_FRAME_USE_POOL 0
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
#define PK_ENABLE_FILEIO 0
#else

View File

@ -163,11 +163,12 @@ struct Frame {
};
#if DEBUG_FRAME_USE_POOL
inline void frame_deleter (Frame* p) { pool256.dealloc(p); }
using Frame_ = std::unique_ptr<Frame, decltype(&frame_deleter)>;
#else
using Frame_ = std::unique_ptr<Frame>;
#endif
struct FrameDeleter{
void operator()(Frame* frame) const {
frame->~Frame();
pool128.dealloc(frame);
}
};
using Frame_ = std::unique_ptr<Frame, FrameDeleter>;
}; // namespace pkpy

View File

@ -11,11 +11,9 @@ struct ManagedHeap{
std::vector<PyObject*> _no_gc;
std::vector<PyObject*> gen;
VM* vm;
MemoryPool<> pool;
ManagedHeap(VM* vm): vm(vm) {}
static const int kMinGCThreshold = 4096;
static const int kMinGCThreshold = 3072;
int gc_threshold = kMinGCThreshold;
int gc_counter = 0;
@ -39,7 +37,7 @@ struct ManagedHeap{
template<typename T>
PyObject* gcnew(Type type, T&& val){
using __T = Py_<std::decay_t<T>>;
PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward<T>(val));
PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward<T>(val));
gen.push_back(obj);
gc_counter++;
return obj;
@ -48,7 +46,7 @@ struct ManagedHeap{
template<typename T>
PyObject* _new(Type type, T&& val){
using __T = Py_<std::decay_t<T>>;
PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward<T>(val));
PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward<T>(val));
obj->gc.enabled = false;
_no_gc.push_back(obj);
return obj;
@ -59,7 +57,7 @@ struct ManagedHeap{
#endif
~ManagedHeap(){
for(PyObject* obj: _no_gc) obj->~PyObject(), pool.dealloc(obj);
for(PyObject* obj: _no_gc) obj->~PyObject(), pool128.dealloc(obj);
#if DEBUG_GC_STATS
for(auto& [type, count]: deleted){
std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
@ -77,7 +75,7 @@ struct ManagedHeap{
#if DEBUG_GC_STATS
deleted[obj->type] += 1;
#endif
obj->~PyObject(), pool.dealloc(obj);
obj->~PyObject(), pool128.dealloc(obj);
}
}

View File

@ -210,6 +210,13 @@ struct MemoryPool{
bool empty() const { return _free_list_size == 0; }
bool full() const { return _free_list_size == __MaxBlocks; }
void tidy(){
#if DEBUG_MEMORY_POOL
if(!full()) throw std::runtime_error("Arena::tidy() called on non-full arena");
#endif
std::sort(_free_list, _free_list+__MaxBlocks);
}
Block* alloc(){
#if DEBUG_MEMORY_POOL
if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena");
@ -244,6 +251,7 @@ struct MemoryPool{
}
if(_arenas.empty()){
// std::cout << _arenas.size() << ',' << _empty_arenas.size() << ',' << _full_arenas.size() << std::endl;
if(_full_arenas.empty()){
_arenas.push_back(new Arena());
}else{
@ -277,6 +285,7 @@ struct MemoryPool{
if(arena->full() && _arenas.size()>2){
_arenas.erase(arena);
if(_full_arenas.size() < FULL_ARENA_SIZE){
// arena->tidy();
_full_arenas.push_back(arena);
}else{
delete arena;
@ -287,9 +296,6 @@ struct MemoryPool{
}
~MemoryPool(){
// std::cout << _arenas.size() << std::endl;
// std::cout << _empty_arenas.size() << std::endl;
// std::cout << _full_arenas.size() << std::endl;
_arenas.apply([](Arena* arena){ delete arena; });
_empty_arenas.apply([](Arena* arena){ delete arena; });
_full_arenas.apply([](Arena* arena){ delete arena; });
@ -298,6 +304,6 @@ struct MemoryPool{
inline MemoryPool<64> pool64;
inline MemoryPool<128> pool128;
inline MemoryPool<256> pool256;
// inline MemoryPool<256> pool256;
}; // namespace pkpy

View File

@ -189,12 +189,8 @@ public:
if(callstack.size() > recursionlimit){
_error("RecursionError", "maximum recursion depth exceeded");
}
#if DEBUG_FRAME_USE_POOL
Frame* frame = new(pool256.alloc(sizeof(Frame))) Frame(std::forward<Args>(args)...);
return Frame_(frame, &frame_deleter);
#else
return std::make_unique<Frame>(std::forward<Args>(args)...);
#endif
Frame* frame = new(pool128.alloc<Frame>()) Frame(std::forward<Args>(args)...);
return Frame_(frame);
}
template<typename ...Args>