changeset 110:be419e04899a

* Update to use BlockAllocator, and a few other bits & pieces
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 14 May 2009 12:45:27 +0000
parents 0dd97d053053
children a8292af48062
files plugins/AdaptiveSpectrogram.cpp plugins/AdaptiveSpectrogram.h
diffstat 2 files changed, 62 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/AdaptiveSpectrogram.cpp	Wed May 13 17:41:41 2009 +0000
+++ b/plugins/AdaptiveSpectrogram.cpp	Thu May 14 12:45:27 2009 +0000
@@ -41,7 +41,8 @@
     }
     m_cutThreads.clear();
 
-    for (FFTMap::iterator i = m_fftThreads.begin(); i != m_fftThreads.end(); ++i) {
+    for (FFTMap::iterator i = m_fftThreads.begin();
+         i != m_fftThreads.end(); ++i) {
         delete i->second;
     }
     m_fftThreads.clear();
@@ -157,7 +158,7 @@
     ParameterDescriptor desc3;
     desc3.identifier = "threaded";
     desc3.name = "Multi-threaded processing";
-    desc3.description = "Perform calculations in several threads in parallel";
+    desc3.description = "Perform calculations using several threads in parallel";
     desc3.unit = "";
     desc3.minValue = 0;
     desc3.maxValue = 1;
@@ -262,7 +263,9 @@
 
     m_threadsInUse = false;
 
-    Cutting *cutting = cut(s, maxwid/2, 0, 0, maxwid/2);
+//    std::cerr << "maxwid/2 = " << maxwid/2 << ", minwid/2 = " << minwid/2 << ", n+1 = " << m_n+1 << ", 2^(n+1) = " << (2<<m_n) << std::endl;
+
+    Cutting *cutting = cut(s, maxwid/2, 0, 0, maxwid/2, 0);
 
 #ifdef DEBUG_VERBOSE
     printCutting(cutting, "  ");
@@ -275,7 +278,7 @@
     
     assemble(s, cutting, rmat, 0, 0, maxwid/minwid, maxwid/2);
 
-    delete cutting;
+    cutting->erase();
 
     for (int i = 0; i < rmat.size(); ++i) {
         Feature f;
@@ -324,15 +327,13 @@
         }
 
         // Cut threads 0 and 1 calculate the top and bottom halves;
-        // threads 2 and 3 calculate left and right.
+        // threads 2 and 3 calculate left and right.  See notes in
+        // unthreaded code below for more information.
 
-        // The "vertical" division is a top/bottom split.
-        // Splitting this way keeps us in the same resolution,
-        // but with two vertical subregions of height h/2.
-        m_cutThreads[0]->cut(s, res, x, y + h/2, h/2); // top
-        m_cutThreads[1]->cut(s, res, x, y, h/2); // bottom
-        m_cutThreads[2]->cut(s, res/2, 2 * x, y/2, h/2); // left
-        m_cutThreads[3]->cut(s, res/2, 2 * x + 1, y/2, h/2); // right
+        m_cutThreads[0]->cut(s, res, x, y + h/2, h/2);        // top
+        m_cutThreads[1]->cut(s, res, x, y, h/2);              // bottom
+        m_cutThreads[2]->cut(s, res/2, 2 * x, y/2, h/2);      // left
+        m_cutThreads[3]->cut(s, res/2, 2 * x + 1, y/2, h/2);  // right
 
         top    = m_cutThreads[0]->get();
         bottom = m_cutThreads[1]->get();
@@ -341,32 +342,42 @@
 
     } else {
 
-        // unthreaded
+        // Unthreaded version
 
         // The "vertical" division is a top/bottom split.
         // Splitting this way keeps us in the same resolution,
         // but with two vertical subregions of height h/2.
 
-        top    = cut(s, res, x, y + h/2, h/2);
-        bottom = cut(s, res, x, y, h/2);
+        top    = cut(s, res, x, y + h/2, h/2, 0);
+        bottom = cut(s, res, x, y, h/2, 0);
 
         // The "horizontal" division is a left/right split.  Splitting
         // this way places us in resolution res/2, which has lower
         // vertical resolution but higher horizontal resolution.  We
         // need to double x accordingly.
         
-        left   = cut(s, res/2, 2 * x, y/2, h/2);
-        right  = cut(s, res/2, 2 * x + 1, y/2, h/2);
+        left   = cut(s, res/2, 2 * x, y/2, h/2, 0);
+        right  = cut(s, res/2, 2 * x + 1, y/2, h/2, 0);
     }
 }
 
 AdaptiveSpectrogram::Cutting *
 AdaptiveSpectrogram::cut(const Spectrograms &s,
                          int res,
-                         int x, int y, int h) const
+                         int x, int y, int h,
+                         BlockAllocator *allocator) const
 {
 //    cerr << "res = " << res << ", x = " << x << ", y = " << y << ", h = " << h << endl;
 
+    Cutting *cutting;
+    if (allocator) {
+        cutting = (Cutting *)(allocator->allocate());
+        cutting->allocator = allocator;
+    } else {
+        cutting = new Cutting;
+        cutting->allocator = 0;
+    }
+
     if (h > 1 && res > s.minres) {
 
         Cutting *top = 0, *bottom = 0, *left = 0, *right = 0;
@@ -389,27 +400,23 @@
         if (vcost > hcost) {
 
             // cut horizontally (left/right)
-
-            Cutting *cutting = new Cutting;
             cutting->cut = Cutting::Horizontal;
             cutting->first = left;
             cutting->second = right;
             cutting->cost = hcost;
-            cutting->value = left->value + right->value;
-            delete top;
-            delete bottom;
+            top->erase();
+            bottom->erase();
             return cutting;
 
         } else {
 
-            Cutting *cutting = new Cutting;
+            // cut vertically (top/bottom)
             cutting->cut = Cutting::Vertical;
             cutting->first = top;
             cutting->second = bottom;
             cutting->cost = vcost;
-            cutting->value = top->value + bottom->value;
-            delete left;
-            delete right;
+            left->erase();
+            right->erase();
             return cutting;
         }
 
@@ -417,7 +424,6 @@
 
         // no cuts possible from this level
 
-        Cutting *cutting = new Cutting;
         cutting->cut = Cutting::Finished;
         cutting->first = 0;
         cutting->second = 0;
--- a/plugins/AdaptiveSpectrogram.h	Wed May 13 17:41:41 2009 +0000
+++ b/plugins/AdaptiveSpectrogram.h	Thu May 14 12:45:27 2009 +0000
@@ -18,6 +18,8 @@
 #include <base/Window.h>
 
 #include "thread/Thread.h"
+#include "thread/AsynchronousTask.h"
+#include "thread/BlockAllocator.h"
 
 class AdaptiveSpectrogram : public Vamp::Plugin
 {
@@ -107,10 +109,21 @@
         Cutting *second;
         double cost;
         double value;
+        BlockAllocator *allocator;
 
         ~Cutting() {
-            delete first;
-            delete second;
+            if (first) first->erase();
+            if (second) second->erase();
+        }
+
+        void erase() {
+            if (allocator) {
+                if (first) first->erase();
+                if (second) second->erase();
+                allocator->deallocate(this);
+            } else {
+                delete this;
+            }
         }
     };
 
@@ -189,8 +202,12 @@
     class CutThread : public AsynchronousTask
     {
     public:
-        CutThread(const AdaptiveSpectrogram *as) : m_as(as), m_result(0) { }
-        ~CutThread() { }
+        CutThread(const AdaptiveSpectrogram *as) : m_as(as), m_result(0) {
+            m_allocator = new BlockAllocator(sizeof(Cutting));
+        }
+        ~CutThread() {
+            delete m_allocator;
+        }
         
         void cut(const Spectrograms &s, int res, int x, int y, int h) {
             m_s = &s;
@@ -208,11 +225,12 @@
 
     protected:
         void performTask() {
-            m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h);
+            m_result = m_as->cut(*m_s, m_res, m_x, m_y, m_h, m_allocator);
         }
 
     private:
         const AdaptiveSpectrogram *m_as;
+        BlockAllocator *m_allocator;
         const Spectrograms *m_s;
         int m_res;
         int m_x;
@@ -224,20 +242,21 @@
     mutable std::vector<CutThread *> m_cutThreads;
     mutable bool m_threadsInUse;
 
-    double xlogx(double x) const {
+    inline double xlogx(double x) const {
         if (x == 0.0) return 0.0;
         else return x * log(x);
     }
 
-    double cost(const Spectrogram &s, int x, int y) const {
+    inline double cost(const Spectrogram &s, int x, int y) const {
         return xlogx(s.data[x][y]);
     }
 
-    double value(const Spectrogram &s, int x, int y) const {
+    inline double value(const Spectrogram &s, int x, int y) const {
         return s.data[x][y];
     }
 
-    Cutting *cut(const Spectrograms &, int res, int x, int y, int h) const;
+    Cutting *cut(const Spectrograms &, int res, int x, int y, int h,
+                 BlockAllocator *allocator) const;
 
     void getSubCuts(const Spectrograms &, int res, int x, int y, int h,
                     Cutting *&top, Cutting *&bottom,