+2011-10-03 Balazs Kelemen <kbalazs@webkit.org>
+
+ libdispatch based ParallelJobs is not enough parallel
+ https://bugs.webkit.org/show_bug.cgi?id=66378
+
+ Reviewed by Zoltan Herczeg.
+
+ Use the appropriate libdispatch API for our use case.
+ Throw away the hard coded limit of parallel threads
+ and use dispatch_apply with the default priority normal
+ queue istead of using our own custom serial queue (which
+ was a misuse of the API). Enabling PARALLEL_JOBS is now
+ a 60% win (2.63x as fast) on the methanol benchmark
+ (https://gitorious.org/methanol) with an SVG centric test set
+ while the old implementation was almost identical (less than 5% win).
+
+ * wtf/ParallelJobsLibdispatch.h:
+ (WTF::ParallelEnvironment::ParallelEnvironment):
+ (WTF::ParallelEnvironment::execute):
+
2011-10-02 Zoltan Herczeg <zherczeg@webkit.org>
[Qt]REGRESSION(r95912): It made sputnik tests flakey
namespace WTF {
-static const int maxParallelThreads = 2;
-
class ParallelEnvironment {
WTF_MAKE_FAST_ALLOCATED;
public:
typedef void (*ThreadFunction)(void*);
- ParallelEnvironment(ThreadFunction threadFunction, size_t sizeOfParameter, int requestedJobNumber) :
- m_threadFunction(threadFunction),
- m_sizeOfParameter(sizeOfParameter)
+ ParallelEnvironment(ThreadFunction threadFunction, size_t sizeOfParameter, int requestedJobNumber)
+ : m_threadFunction(threadFunction)
+ , m_sizeOfParameter(sizeOfParameter)
+ , m_numberOfJobs(requestedJobNumber)
{
- if (!requestedJobNumber || requestedJobNumber > maxParallelThreads)
- requestedJobNumber = maxParallelThreads;
-
- ASSERT(requestedJobNumber > 0);
-
- m_numberOfJobs = requestedJobNumber;
+ // We go with the requested number of jobs. libdispatch will distribute the work optimally.
+ ASSERT_ARG(requestedJobNumber, requestedJobNumber > 0);
}
int numberOfJobs()
void execute(unsigned char* parameters)
{
- // libdispatch is NOT supported inside a template
- dispatch_queue_t parallelJobsQueue = dispatch_queue_create("ParallelJobs", 0);
-
- for (int i = 0; i < m_numberOfJobs - 1; ++i) {
- dispatch_async(parallelJobsQueue, ^{(*m_threadFunction)(parameters);});
- parameters += m_sizeOfParameter;
- }
+ static dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- // The work for the main thread. Wait until all jobs are done.
- dispatch_sync(parallelJobsQueue, ^{(*m_threadFunction)(parameters);});
+ dispatch_apply(m_numberOfJobs, globalQueue, ^(size_t i) { (*m_threadFunction)(parameters + (m_sizeOfParameter * i)); });
}
private: