Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2079 - in trunk: Core/Geometry Core/Thread Core/Util Model/Groups


Chronological Thread 
  • From: "Solomon Boulos" <boulos@cs.utah.edu>
  • To: manta@sci.utah.edu
  • Subject: [Manta] r2079 - in trunk: Core/Geometry Core/Thread Core/Util Model/Groups
  • Date: Fri, 15 Feb 2008 15:37:29 -0700 (MST)

Author: boulos
Date: Fri Feb 15 15:37:26 2008
New Revision: 2079

Modified:
   trunk/Core/Geometry/BBox.h
   trunk/Core/Thread/AtomicCounter.h
   trunk/Core/Thread/AtomicCounter_x86.cc
   trunk/Core/Thread/Thread_pthreads.cc
   trunk/Core/Util/SpinLock.h
   trunk/Model/Groups/DynBVH.cc
Log:
Core/Geometry/BBox.h
Core/Thread/AtomicCounter.h
Core/Thread/AtomicCounter_x86.cc
Core/Thread/Thread_pthreads.cc
Core/Util/SpinLock.h

 Adding inline to many commonly used functions (GCC isn't very aggressive w/o 
it)

 Detect whether or not we should use the X86 atomic counter in the
 header so we can inline it. AtomicCounter_x86.cc still exists to
 perform construction (didn't want to get a cyclic dependency on
 Thread::initialize).

 Add 128-byte line padding to the optimized AtomicCounter.

 Change constraint modifiers to +r and +m instead of =r and =m. Also
 adding __volatile__ to all registers (came up after moving this code to
 be inlined)

 Changing SpinLock to use ifdef MANTA_X86 instead of if (as is the Manta 
convention).

Model/Groups/DynBVH.cc

 Adjusting some parameters for parallel BVH build and adding a helper
 function to write out the mesh in BVH sorted order.


Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h  (original)
+++ trunk/Core/Geometry/BBox.h  Fri Feb 15 15:37:26 2008
@@ -16,11 +16,11 @@
       bounds[0] = min_;
       bounds[1] = max_;
     }
-    BBox() {
+    inline BBox() {
       // Need to initialize min and max.
       reset();
     }
-    ~BBox() {
+    inline ~BBox() {
     }
     BBox(const BBox& copy)
     {
@@ -39,13 +39,13 @@
 
     // This resets min and max to an uninitialized state that will
     // accept new bounds [MAX, -MAX].
-    void reset() {
+    inline void reset() {
       Real max_val = std::numeric_limits<Real>::max();
       bounds[0] = Vector( max_val,  max_val,  max_val);
       bounds[1] = Vector(-max_val, -max_val, -max_val);
     }
 
-    void reset( const Vector& min_, const Vector& max_ ) {
+    inline void reset( const Vector& min_, const Vector& max_ ) {
       bounds[0] = min_;
       bounds[1] = max_;
     }
@@ -64,7 +64,7 @@
       return Interpolate(bounds[0], bounds[1], (Real)0.5);
     }
 
-    void extendByPoint(const Vector& p) {
+    inline void extendByPoint(const Vector& p) {
       bounds[0] = Min(bounds[0], p);
       bounds[1] = Max(bounds[1], p);
     }
@@ -82,7 +82,7 @@
       bounds[0] = Min(bounds[0], p-v);
       bounds[1] = Max(bounds[1], p+v);
     }
-    void extendByBox(const BBox& b) {
+    inline void extendByBox(const BBox& b) {
       bounds[0] = Min(bounds[0], b.bounds[0]);
       bounds[1] = Max(bounds[1], b.bounds[1]);
     }
@@ -92,10 +92,10 @@
       bounds[1] = Min(bounds[1], b.bounds[1]);
     }
 
-    const Vector& getMin() const {
+    inline const Vector& getMin() const {
       return bounds[0];
     }
-    const Vector& getMax() const {
+    inline const Vector& getMax() const {
       return bounds[1];
     }
 
@@ -111,7 +111,7 @@
       return ( d.x() * d.y() * d.z() );
     }
 
-    double computeArea() const
+    inline double computeArea() const
     {
       Vector d = bounds[1] - bounds[0];
       return 2 * (d.x()*d.y() + d.y()*d.z() + d.x()*d.z());

Modified: trunk/Core/Thread/AtomicCounter.h
==============================================================================
--- trunk/Core/Thread/AtomicCounter.h   (original)
+++ trunk/Core/Thread/AtomicCounter.h   Fri Feb 15 15:37:26 2008
@@ -43,6 +43,13 @@
 #ifndef Core_Thread_AtomicCounter_h
 #define Core_Thread_AtomicCounter_h
 
+#include <MachineParameters.h>
+
+#if defined(MANTA_X86) && !defined(_WIN32)
+  #define USE_ATOMIC_COUNTER_X86
+#endif
+
+
 namespace Manta {
 
 class AtomicCounter_private;
@@ -122,15 +129,121 @@
 
 private:
   const char* name_;
-  AtomicCounter_private* priv_;
-  // NOTE(boulos): We could additionally add a check for MANTA_X86
-  // here as this is the only code that relies on it.
+#ifdef USE_ATOMIC_COUNTER_X86
   int value;
-
+  char padding[128 - sizeof(int) - sizeof(const char*)];
+#else
+  AtomicCounter_private* priv_;
+#endif
   // Cannot copy them
   AtomicCounter(const AtomicCounter&);
   AtomicCounter& operator=(const AtomicCounter&);
 };
+
+
+#ifdef USE_ATOMIC_COUNTER_X86
+/*
+ *  AtomicCounter: Thread-safe integer variable written in x86 assembly
+ *
+ *  Written by:
+ *   Author: Solomon Boulos
+ *   Department of Computer Science
+ *   University of Utah
+ *   Date: 10-Sep-2007
+ *
+ */
+inline AtomicCounter::operator int() const {
+  return value;
+}
+
+inline
+int
+AtomicCounter::operator++() {
+  __volatile__ register int return_val = 1;
+
+  __asm__ __volatile__(
+      "lock;\n"
+      "xaddl %1, %0;\n" :
+      "+m" (value), "+r"(return_val) :
+      "m" (value) , "r" (return_val) :
+      /* no unknown clobbers */
+    );
+  return return_val + 1;
+}
+
+inline
+int
+AtomicCounter::operator++(int) {
+  __volatile__ register int return_val = 1;
+
+  __asm__ __volatile__(
+      "lock;\n"
+      "xaddl %1, %0;\n" :
+      "+m" (value), "+r"(return_val) :
+      "m" (value) , "r" (return_val) :
+      /* no unknown clobbers */
+    );
+  return return_val;
+}
+
+inline
+int
+AtomicCounter::operator+=(int val) {
+  __volatile__ register int return_val = val;
+
+  __asm__ __volatile__(
+      "lock;\n"
+      "xaddl %1, %0;\n" :
+      "+m" (value), "+r"(return_val) :
+      "m" (value) , "r" (return_val), "r" (val) :
+      /* no unknown clobbers */
+    );
+  return return_val;
+}
+
+inline
+int
+AtomicCounter::operator--() {
+  __volatile__ register int return_val = -1;
+  __asm__ __volatile__(
+      "lock;\n"
+      "xaddl %1, %0;\n" :
+      "+m" (value), "+r"(return_val) :
+      "m" (value) , "r" (return_val) :
+      /* no unknown clobbers */
+    );
+  return return_val - 1;
+}
+
+inline
+int
+AtomicCounter::operator--(int) {
+  __volatile__ register int return_val = -1;
+  __asm__ __volatile__(
+      "lock;\n"
+      "xaddl %1, %0;\n" :
+      "+m" (value), "+r"(return_val) :
+      "m" (value) , "r" (return_val) :
+      /* no unknown clobbers */
+    );
+  // The exchange returns the old value
+  return return_val;
+}
+
+inline
+void
+AtomicCounter::set(int v) {
+  __volatile__ register int copy_val = v;
+  __asm__ __volatile__(
+    "lock;\n"
+    "xchgl %1, %0\n" :
+    "+m" (value), "+r" (copy_val) :
+    "m" (value), "r" (copy_val), "r" (v) :
+    /* no unknown clobbers */
+    );
+}
+#endif // USE_ATOMIC_COUNTER_X86
+
 }
 
 #endif

Modified: trunk/Core/Thread/AtomicCounter_x86.cc
==============================================================================
--- trunk/Core/Thread/AtomicCounter_x86.cc      (original)
+++ trunk/Core/Thread/AtomicCounter_x86.cc      Fri Feb 15 15:37:26 2008
@@ -26,25 +26,10 @@
    DEALINGS IN THE SOFTWARE.
 */
 
-
-
-/*
- *  AtomicCounter: Thread-safe integer variable written in x86 assembly
- *
- *  Written by:
- *   Author: Solomon Boulos
- *   Department of Computer Science
- *   University of Utah
- *   Date: 10-Sep-2007
- *
- */
-
-#include <Core/Thread/AtomicCounter.h>
-
 using Manta::AtomicCounter;
 
 AtomicCounter::AtomicCounter(const char* name)
-  : name_(name), priv_(0), value(0)
+  : name_(name), value(0)
 {
   if(!Thread::isInitialized()){
     if(getenv("THREAD_SHOWINIT"))
@@ -55,92 +40,13 @@
 
 AtomicCounter::AtomicCounter(const char* name, int value)
   : name_(name), value(value) {
+  if(!Thread::isInitialized()){
+    if(getenv("THREAD_SHOWINIT"))
+      fprintf(stderr, "AtomicCounter: %s\n", name);
+    Thread::initialize();
+  }
 }
 
 AtomicCounter::~AtomicCounter() {
 }
 
-AtomicCounter::operator int() const {
-  return value;
-}
-
-int
-AtomicCounter::operator++() {
-  register int return_val = 1;
-
-  __asm__ __volatile__(
-      "lock;\n"
-      "xaddl %1, %0;\n" :
-      "=m" (value), "=r"(return_val) :
-      "m" (value) , "r" (return_val) :
-      /* no unknown clobbers */
-    );
-  return return_val + 1;
-}
-
-int
-AtomicCounter::operator++(int) {
-  register int return_val = 1;
-
-  __asm__ __volatile__(
-      "lock;\n"
-      "xaddl %1, %0;\n" :
-      "=m" (value), "=r"(return_val) :
-      "m" (value) , "r" (return_val) :
-      /* no unknown clobbers */
-    );
-  return return_val;
-}
-
-int
-AtomicCounter::operator+=(int val) {
-  __volatile__ register int return_val = val;
-
-  __asm__ __volatile__(
-      "lock;\n"
-      "xaddl %1, %0;\n" :
-      "=m" (value), "=r"(return_val) :
-      "m" (value) , "r" (return_val), "r" (val) :
-      /* no unknown clobbers */
-    );
-  return return_val;
-}
-
-int
-AtomicCounter::operator--() {
-  register int return_val = -1;
-  __asm__ __volatile__(
-      "lock;\n"
-      "xaddl %1, %0;\n" :
-      "=m" (value), "=r"(return_val) :
-      "m" (value) , "r" (return_val) :
-      /* no unknown clobbers */
-    );
-  return return_val - 1;
-}
-
-int
-AtomicCounter::operator--(int) {
-  register int return_val = -1;
-  __asm__ __volatile__(
-      "lock;\n"
-      "xaddl %1, %0;\n" :
-      "=m" (value), "=r"(return_val) :
-      "m" (value) , "r" (return_val) :
-      /* no unknown clobbers */
-    );
-  // The exchange returns the old value
-  return return_val;
-}
-
-void
-AtomicCounter::set(int v) {
-  __volatile__ register int copy_val = v;
-  __asm__ __volatile__(
-    "lock;\n"
-    "xchgl %1, %0\n" :
-    "=m" (value), "=r" (copy_val) :
-    "m" (value), "r" (copy_val), "r" (v) :
-    /* no unknown clobbers */
-    );
-}

Modified: trunk/Core/Thread/Thread_pthreads.cc
==============================================================================
--- trunk/Core/Thread/Thread_pthreads.cc        (original)
+++ trunk/Core/Thread/Thread_pthreads.cc        Fri Feb 15 15:37:26 2008
@@ -159,15 +159,10 @@
 #ifndef __ia64__
 #include <Core/Thread/Barrier_default.cc>
 
-#ifdef MANTA_X86
-#  if !defined(__INTEL_COMPILER)
-#    include <Core/Thread/AtomicCounter_x86.cc>
-#  else
-//AtomicCounter_x86 is currently broken for ICC.
-#    include <Core/Thread/AtomicCounter_default.cc>
-#  endif // intel compiler or not
-#else // manta_x86 or not
-#include <Core/Thread/AtomicCounter_default.cc>
+#ifndef USE_ATOMIC_COUNTER_X86
+#  include <Core/Thread/AtomicCounter_default.cc>
+#else
+#  include <Core/Thread/AtomicCounter_x86.cc>
 #endif
 #endif
 #include <Core/Thread/CrowdMonitor_default.cc>

Modified: trunk/Core/Util/SpinLock.h
==============================================================================
--- trunk/Core/Util/SpinLock.h  (original)
+++ trunk/Core/Util/SpinLock.h  Fri Feb 15 15:37:26 2008
@@ -3,12 +3,12 @@
 
 #include <MachineParameters.h>
 
-#if !(MANTA_X86)
+#ifndef MANTA_X86
 #include <Core/Thread/Mutex.h>
 #endif
 
 namespace Manta {
-#if MANTA_X86
+#ifdef MANTA_X86
   class SpinLock {
   public:
     SpinLock() : value(0) {

Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Fri Feb 15 15:37:26 2008
@@ -25,6 +25,30 @@
 const float BVH_C_isec = 10.f;
 const float BVH_C_trav = 10.f;
 
+#include <Model/Groups/Mesh.h>
+void WriteMeshSorted(Group* group, std::vector<int> ids, const char* 
filename) {
+  FILE* output = fopen(filename, "w");
+  Mesh* mesh = dynamic_cast<Mesh*>(group);
+  // Write out the verts
+  std::vector<Vector>& verts = mesh->vertices;
+  for (size_t i = 0; i < verts.size(); i++) {
+    fprintf(output, "v %f %f %f\n", verts[i][0], verts[i][1], verts[i][2]);
+  }
+  fprintf(output, "\n");
+  // Write out the faces but in the order the BVH produced
+  std::vector<unsigned int>& indices = mesh->vertex_indices;
+  for (size_t i = 0; i < ids.size(); i++) {
+    int which_tri = ids[i];
+    int index = 3 * which_tri;
+    fprintf(output, "f %d %d %d\n",
+            indices[index + 0] + 1,
+            indices[index + 1] + 1,
+            indices[index + 2] + 1);
+  }
+  fprintf(output, "\n");
+  fclose(output);
+}
+
 DynBVH::~DynBVH()
 {
   //  cerr << MANTA_FUNC << " called.\n";
@@ -711,6 +735,9 @@
     FiveArgCallbackMemory = 0;
   }
 
+  //WriteMeshSorted(currGroup, object_ids, "sorted.obj");
+  //exit(-1);
+
   context.finish(this);
 }
 
@@ -1208,7 +1235,7 @@
 void DynBVH::parallelTopDownBuild(Task* task, int nodeID, int objectBegin, 
int objectEnd, UpdateContext context) {
   //cerr << MANTA_FUNC << "(nodeId = " << nodeID << ", objectBegin = " << 
objectBegin << ", objectEnd = " << objectEnd << ")\n";
   int num_objects = objectEnd - objectBegin;
-  const int kSmallObjects = 1024;
+  const int kSmallObjects = 2048;
   PreprocessContext preprocess_context(context.manta_interface,
                                        context.proc,
                                        context.num_procs,




  • [Manta] r2079 - in trunk: Core/Geometry Core/Thread Core/Util Model/Groups, Solomon Boulos, 02/15/2008

Archive powered by MHonArc 2.6.16.

Top of page