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

@ -3,4 +3,6 @@ def fib(n):
return n return n
return fib(n-1) + fib(n-2) return fib(n-1) + fib(n-2)
assert fib(32) == 2178309 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_NO_AUTO_GC 0
#define DEBUG_GC_STATS 0 #define DEBUG_GC_STATS 0
#define DEBUG_FRAME_USE_POOL 0
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__) #if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
#define PK_ENABLE_FILEIO 0 #define PK_ENABLE_FILEIO 0
#else #else

View File

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

View File

@ -11,11 +11,9 @@ struct ManagedHeap{
std::vector<PyObject*> _no_gc; std::vector<PyObject*> _no_gc;
std::vector<PyObject*> gen; std::vector<PyObject*> gen;
VM* vm; VM* vm;
MemoryPool<> pool;
ManagedHeap(VM* vm): vm(vm) {} ManagedHeap(VM* vm): vm(vm) {}
static const int kMinGCThreshold = 4096; static const int kMinGCThreshold = 3072;
int gc_threshold = kMinGCThreshold; int gc_threshold = kMinGCThreshold;
int gc_counter = 0; int gc_counter = 0;
@ -39,7 +37,7 @@ struct ManagedHeap{
template<typename T> template<typename T>
PyObject* gcnew(Type type, T&& val){ PyObject* gcnew(Type type, T&& val){
using __T = Py_<std::decay_t<T>>; 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); gen.push_back(obj);
gc_counter++; gc_counter++;
return obj; return obj;
@ -48,7 +46,7 @@ struct ManagedHeap{
template<typename T> template<typename T>
PyObject* _new(Type type, T&& val){ PyObject* _new(Type type, T&& val){
using __T = Py_<std::decay_t<T>>; 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; obj->gc.enabled = false;
_no_gc.push_back(obj); _no_gc.push_back(obj);
return obj; return obj;
@ -59,7 +57,7 @@ struct ManagedHeap{
#endif #endif
~ManagedHeap(){ ~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 #if DEBUG_GC_STATS
for(auto& [type, count]: deleted){ for(auto& [type, count]: deleted){
std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl; std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
@ -77,7 +75,7 @@ struct ManagedHeap{
#if DEBUG_GC_STATS #if DEBUG_GC_STATS
deleted[obj->type] += 1; deleted[obj->type] += 1;
#endif #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 empty() const { return _free_list_size == 0; }
bool full() const { return _free_list_size == __MaxBlocks; } 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(){ Block* alloc(){
#if DEBUG_MEMORY_POOL #if DEBUG_MEMORY_POOL
if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena"); if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena");
@ -244,6 +251,7 @@ struct MemoryPool{
} }
if(_arenas.empty()){ if(_arenas.empty()){
// std::cout << _arenas.size() << ',' << _empty_arenas.size() << ',' << _full_arenas.size() << std::endl;
if(_full_arenas.empty()){ if(_full_arenas.empty()){
_arenas.push_back(new Arena()); _arenas.push_back(new Arena());
}else{ }else{
@ -277,6 +285,7 @@ struct MemoryPool{
if(arena->full() && _arenas.size()>2){ if(arena->full() && _arenas.size()>2){
_arenas.erase(arena); _arenas.erase(arena);
if(_full_arenas.size() < FULL_ARENA_SIZE){ if(_full_arenas.size() < FULL_ARENA_SIZE){
// arena->tidy();
_full_arenas.push_back(arena); _full_arenas.push_back(arena);
}else{ }else{
delete arena; delete arena;
@ -287,9 +296,6 @@ struct MemoryPool{
} }
~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; }); _arenas.apply([](Arena* arena){ delete arena; });
_empty_arenas.apply([](Arena* arena){ delete arena; }); _empty_arenas.apply([](Arena* arena){ delete arena; });
_full_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<64> pool64;
inline MemoryPool<128> pool128; inline MemoryPool<128> pool128;
inline MemoryPool<256> pool256; // inline MemoryPool<256> pool256;
}; // namespace pkpy }; // namespace pkpy

View File

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