Browse Source

Clamp max. amount of worker threads.

Lasse Öörni 14 years ago
parent
commit
d29885dd9f

+ 1 - 5
Engine/Core/WorkQueue.cpp

@@ -23,7 +23,6 @@
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "ProcessUtils.h"
 #include "ProcessUtils.h"
-#include "Profiler.h"
 #include "WorkerThread.h"
 #include "WorkerThread.h"
 #include "WorkQueue.h"
 #include "WorkQueue.h"
 
 
@@ -105,7 +104,7 @@ WorkQueue::WorkQueue(Context* context) :
     int numCores = GetNumCPUCores();
     int numCores = GetNumCPUCores();
     if (numCores == 1)
     if (numCores == 1)
         return;
         return;
-    int numThreads = Max(numCores - 2, 1);
+    int numThreads = Clamp(numCores - 2, 1, 4);
     
     
     for (int i = 0; i < numThreads; ++i)
     for (int i = 0; i < numThreads; ++i)
     {
     {
@@ -141,10 +140,7 @@ void WorkQueue::AddWorkItem(const WorkItem& item)
         bool isWaiting = numWaiting_ > 0;
         bool isWaiting = numWaiting_ > 0;
         queueLock_.Release();
         queueLock_.Release();
         if (isWaiting)
         if (isWaiting)
-        {
-            PROFILE(SignalWorkerThreads);
             impl_->Signal();
             impl_->Signal();
-        }
     }
     }
     else
     else
         item.workFunction_(&item, 0);
         item.workFunction_(&item, 0);

+ 1 - 1
Engine/Core/WorkQueue.h

@@ -79,7 +79,7 @@ private:
     /// Queue lock.
     /// Queue lock.
     SpinLock queueLock_;
     SpinLock queueLock_;
     /// Number of waiting threads.
     /// Number of waiting threads.
-    unsigned numWaiting_;
+    volatile unsigned numWaiting_;
     /// Shutting down flag.
     /// Shutting down flag.
     volatile bool shutDown_;
     volatile bool shutDown_;
 };
 };

+ 2 - 2
Engine/Graphics/Octree.cpp

@@ -458,7 +458,7 @@ void Octree::UpdateDrawables(const FrameInfo& frame)
     if (drawableUpdates_.Empty())
     if (drawableUpdates_.Empty())
         return;
         return;
     
     
-    PROFILE_MULTIPLE(UpdateDrawable, drawableUpdates_.Size());
+    PROFILE(UpdateDrawables);
     
     
     Scene* scene = node_->GetScene();
     Scene* scene = node_->GetScene();
     WorkQueue* queue = GetSubsystem<WorkQueue>();
     WorkQueue* queue = GetSubsystem<WorkQueue>();
@@ -499,7 +499,7 @@ void Octree::ReinsertDrawables(const FrameInfo& frame)
     if (drawableReinsertions_.Empty())
     if (drawableReinsertions_.Empty())
         return;
         return;
     
     
-    PROFILE_MULTIPLE(ReinsertDrawable, drawableReinsertions_.Size());
+    PROFILE(ReinsertDrawables);
     
     
     // Reinsert drawables into the octree
     // Reinsert drawables into the octree
     for (PODVector<Drawable*>::Iterator i = drawableReinsertions_.Begin(); i != drawableReinsertions_.End(); ++i)
     for (PODVector<Drawable*>::Iterator i = drawableReinsertions_.Begin(); i != drawableReinsertions_.End(); ++i)

+ 58 - 63
Engine/Graphics/View.cpp

@@ -624,53 +624,78 @@ void View::GetBatches()
             }
             }
         }
         }
     }
     }
-    
-    // All batches have been collected. Sort them now
-    SortBatches();
 }
 }
 
 
 void View::UpdateGeometries()
 void View::UpdateGeometries()
 {
 {
-    // Split into threaded and non-threaded geometries.
-    nonThreadedGeometries_.Clear();
-    threadedGeometries_.Clear();
-    for (PODVector<Drawable*>::Iterator i = allGeometries_.Begin(); i != allGeometries_.End(); ++i)
-    {
-        UpdateGeometryType type = (*i)->GetUpdateGeometryType();
-        if (type == UPDATE_MAIN_THREAD)
-            nonThreadedGeometries_.Push(*i);
-        else if (type == UPDATE_WORKER_THREAD)
-            threadedGeometries_.Push(*i);
-    }
-    
-    PROFILE_MULTIPLE(UpdateGeometry, nonThreadedGeometries_.Size() + threadedGeometries_.Size());
+    PROFILE(UpdateGeometries);
     
     
     WorkQueue* queue = GetSubsystem<WorkQueue>();
     WorkQueue* queue = GetSubsystem<WorkQueue>();
     
     
-    if (threadedGeometries_.Size())
+    // Sort batches
     {
     {
-        PODVector<Drawable*>::Iterator start = threadedGeometries_.Begin();
-        while (start != threadedGeometries_.End())
+        WorkItem item;
+        
+        item.workFunction_ = SortBatchQueueFrontToBackWork;
+        item.start_ = &baseQueue_;
+        queue->AddWorkItem(item);
+        item.start_ = &preAlphaQueue_;
+        queue->AddWorkItem(item);
+        
+        item.workFunction_ = SortBatchQueueBackToFrontWork;
+        item.start_ = &alphaQueue_;
+        queue->AddWorkItem(item);
+        item.start_ = &postAlphaQueue_;
+        queue->AddWorkItem(item);
+
+        if (lightQueues_.Size())
         {
         {
-            PODVector<Drawable*>::Iterator end = start;
-            while (end - start < DRAWABLES_PER_WORK_ITEM && end != threadedGeometries_.End())
-                ++end;
-            
-            WorkItem item;
-            item.workFunction_ = UpdateDrawableGeometriesWork;
-            item.start_ = &(*start);
-            item.end_ = &(*end);
-            item.aux_ = const_cast<FrameInfo*>(&frame_);
+            item.workFunction_ = SortLightQueuesWork;
+            item.start_ = &lightQueues_.Front();
+            item.end_ = &lightQueues_.Back() + 1;
             queue->AddWorkItem(item);
             queue->AddWorkItem(item);
-            
-            start = end;
         }
         }
     }
     }
     
     
-    // While the work queue is processed, update non-threaded geometries
-    for (PODVector<Drawable*>::ConstIterator i = nonThreadedGeometries_.Begin(); i != nonThreadedGeometries_.End(); ++i)
-        (*i)->UpdateGeometry(frame_);
+    // Update geometries. Split into threaded and non-threaded updates.
+    {
+        nonThreadedGeometries_.Clear();
+        threadedGeometries_.Clear();
+        for (PODVector<Drawable*>::Iterator i = allGeometries_.Begin(); i != allGeometries_.End(); ++i)
+        {
+            UpdateGeometryType type = (*i)->GetUpdateGeometryType();
+            if (type == UPDATE_MAIN_THREAD)
+                nonThreadedGeometries_.Push(*i);
+            else if (type == UPDATE_WORKER_THREAD)
+                threadedGeometries_.Push(*i);
+        }
+        
+        if (threadedGeometries_.Size())
+        {
+            PODVector<Drawable*>::Iterator start = threadedGeometries_.Begin();
+            while (start != threadedGeometries_.End())
+            {
+                PODVector<Drawable*>::Iterator end = start;
+                while (end - start < DRAWABLES_PER_WORK_ITEM && end != threadedGeometries_.End())
+                    ++end;
+                
+                WorkItem item;
+                item.workFunction_ = UpdateDrawableGeometriesWork;
+                item.start_ = &(*start);
+                item.end_ = &(*end);
+                item.aux_ = const_cast<FrameInfo*>(&frame_);
+                queue->AddWorkItem(item);
+                
+                start = end;
+            }
+        }
+        
+        // While the work queue is processed, update non-threaded geometries
+        for (PODVector<Drawable*>::ConstIterator i = nonThreadedGeometries_.Begin(); i != nonThreadedGeometries_.End(); ++i)
+            (*i)->UpdateGeometry(frame_);
+    }
     
     
+    // Finally ensure all threaded work has completed
     queue->Complete();
     queue->Complete();
 }
 }
 
 
@@ -1665,36 +1690,6 @@ void View::FinalizeBatch(Batch& batch, Technique* tech, Pass* pass, bool allowIn
     batch.CalculateSortKey();
     batch.CalculateSortKey();
 }
 }
 
 
-void View::SortBatches()
-{
-    PROFILE(SortBatches);
-    
-    WorkQueue* queue = GetSubsystem<WorkQueue>();
-    WorkItem item;
-    
-    item.workFunction_ = SortBatchQueueFrontToBackWork;
-    item.start_ = &baseQueue_;
-    queue->AddWorkItem(item);
-    item.start_ = &preAlphaQueue_;
-    queue->AddWorkItem(item);
-    
-    item.workFunction_ = SortBatchQueueBackToFrontWork;
-    item.start_ = &alphaQueue_;
-    queue->AddWorkItem(item);
-    item.start_ = &postAlphaQueue_;
-    queue->AddWorkItem(item);
-
-    if (lightQueues_.Size())
-    {
-        item.workFunction_ = SortLightQueuesWork;
-        item.start_ = &lightQueues_.Front();
-        item.end_ = &lightQueues_.Back() + 1;
-        queue->AddWorkItem(item);
-    }
-    
-    queue->Complete();
-}
-
 void View::PrepareInstancingBuffer()
 void View::PrepareInstancingBuffer()
 {
 {
     PROFILE(PrepareInstancingBuffer);
     PROFILE(PrepareInstancingBuffer);

+ 2 - 4
Engine/Graphics/View.h

@@ -63,7 +63,7 @@ public:
     
     
     /// Define with rendertarget and viewport. Return true if successful.
     /// Define with rendertarget and viewport. Return true if successful.
     bool Define(RenderSurface* renderTarget, const Viewport& viewport);
     bool Define(RenderSurface* renderTarget, const Viewport& viewport);
-    /// Update culling and construct rendering batches.
+    /// Update and cull objects and construct rendering batches.
     void Update(const FrameInfo& frame);
     void Update(const FrameInfo& frame);
     /// Render batches.
     /// Render batches.
     void Render();
     void Render();
@@ -92,7 +92,7 @@ private:
     void GetDrawables();
     void GetDrawables();
     /// Construct batches from the drawable objects.
     /// Construct batches from the drawable objects.
     void GetBatches();
     void GetBatches();
-    /// Prepare GPU resources of drawable objects. Must be called from the main thread.
+    /// Update geometries and sort batches.
     void UpdateGeometries();
     void UpdateGeometries();
     /// Get lit batches for a certain light and drawable.
     /// Get lit batches for a certain light and drawable.
     void GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue);
     void GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue);
@@ -138,8 +138,6 @@ private:
     void CheckMaterialForAuxView(Material* material);
     void CheckMaterialForAuxView(Material* material);
     /// Finalize a batch. Convert it to instanced if possible, choose shaders for it, and calculate the sort key.
     /// Finalize a batch. Convert it to instanced if possible, choose shaders for it, and calculate the sort key.
     void FinalizeBatch(Batch& batch, Technique* tech, Pass* pass, bool allowInstancing = true, bool allowShadows = true);
     void FinalizeBatch(Batch& batch, Technique* tech, Pass* pass, bool allowInstancing = true, bool allowShadows = true);
-    /// Sort all batches.
-    void SortBatches();
     /// Prepare instancing buffer by filling it with all instance transforms.
     /// Prepare instancing buffer by filling it with all instance transforms.
     void PrepareInstancingBuffer();
     void PrepareInstancingBuffer();
     /// Render everything in a batch queue, priority batches first.
     /// Render everything in a batch queue, priority batches first.