blueloveTH vor 2 Jahren
Ursprung
Commit
ef3e172fbd
7 geänderte Dateien mit 32 neuen und 26 gelöschten Zeilen
  1. 3 1
      benchmarks/fib.py
  2. 5 0
      run_profile.sh
  3. 0 2
      src/common.h
  4. 7 6
      src/frame.h
  5. 5 7
      src/gc.h
  6. 10 4
      src/memory.h
  7. 2 6
      src/vm.h

+ 3 - 1
benchmarks/fib.py

@@ -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 - 0
run_profile.sh

@@ -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

+ 0 - 2
src/common.h

@@ -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

+ 7 - 6
src/frame.h

@@ -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
 }; // namespace pkpy

+ 5 - 7
src/gc.h

@@ -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);
             }
             }
         }
         }
 
 

+ 10 - 4
src/memory.h

@@ -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

+ 2 - 6
src/vm.h

@@ -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(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>
     template<typename ...Args>