Skip to content

Commit

Permalink
Added Enhanced Guided Self Scheduler (EGSScheduler). Now to add predi…
Browse files Browse the repository at this point in the history
…ctive

scheduler that doesn't suck like the last one...
  • Loading branch information
rickwebiii committed Apr 4, 2012
1 parent 22f7b8b commit 509cc64
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 12 deletions.
21 changes: 20 additions & 1 deletion Include/clUtilScheduler.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "clUtilCommon.h"
#include "clUtilDeviceGroup.h"

namespace clUtil
{
Expand Down Expand Up @@ -30,6 +31,7 @@ namespace clUtil
}
};
}

class IScheduler
{
public:
Expand All @@ -51,7 +53,8 @@ namespace clUtil
class StaticScheduler : public IScheduler
{
public:
StaticScheduler(size_t numChunks) :
StaticScheduler(size_t numChunks = 30) :
IScheduler(),
mNumChunks(numChunks),
mChunkSize(0),
mNextIteration(0)
Expand All @@ -67,5 +70,21 @@ namespace clUtil
size_t mChunkSize;
size_t mNextIteration;
};

class EGSScheduler : public IScheduler
{
public:
EGSScheduler();
virtual Utility::IndexRange getWork(const size_t deviceGroup);
virtual void updateModel(const Utility::DeviceStatus& status);
virtual bool workRemains(size_t deviceGroup) const;
virtual void setRange(Utility::IndexRange& range);

private:
std::vector<Utility::IndexRange> mTasks;
std::vector<bool> mTasksValid;
std::vector<size_t> mPerformanceRank;
size_t mNextIteration;
};
}

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include Makefile.inc
OBJ=clUtil.o clUtilKernel.o clUtilInit.o clUtilDevice.o
OBJ+=clUtilPlatform.o clUtilUtility.o clUtilDeviceHelpers.o clUtilMemory.o
OBJ+=clUtilParallelFor.o clUtilDeviceGroup.o
OBJ+=Scheduler/StaticScheduler.o
OBJ+=Scheduler/StaticScheduler.o Scheduler/EGSScheduler.o
EXAMPLES=$(wildcard examples/*) #Every subdir in examples

#Directory containing OpenCL header files
Expand Down
153 changes: 153 additions & 0 deletions Scheduler/EGSScheduler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include "clUtilScheduler.h"

using namespace std;
using namespace clUtil;
using namespace clUtil::Utility;

EGSScheduler::EGSScheduler() :
IScheduler(),
mTasks(clUtil::DeviceGroupInfo::Get().numGroups()),
mTasksValid(clUtil::DeviceGroupInfo::Get().numGroups(), false),
mPerformanceRank(clUtil::DeviceGroupInfo::Get().numGroups()),
mNextIteration(0)
{
size_t numDeviceGroups = clUtil::DeviceGroupInfo::Get().numGroups();

std::vector<unsigned int> performance(numDeviceGroups);

const DeviceGroupInfo& groupInfo = DeviceGroupInfo::Get();

//Compute a heuristic (e.g. bullshit) performance metric for each
//device group
for(size_t curDeviceNum = 0;
curDeviceNum < Device::GetDevices().size();
curDeviceNum++)
{
const Device& curDevice = Device::GetDevices()[curDeviceNum];
const DeviceInfo& deviceInfo = curDevice.getDeviceInfo();

unsigned int estimatedPerformance = 1;

estimatedPerformance *= deviceInfo.Type == CL_DEVICE_TYPE_GPU ? 16 : 1;
estimatedPerformance *= deviceInfo.MaxComputeUnits;

performance[groupInfo[curDeviceNum]] = estimatedPerformance;
}

//Now actually rank the performances
for(size_t performanceRank = 0;
performanceRank < numDeviceGroups;
performanceRank++)
{
unsigned int maxPerformance = 0;
unsigned int maxPerformanceIdx = 0;

//Find the maximum performance
for(size_t i = 0; i < performance.size(); i++)
{
if(performance[i] > maxPerformance)
{
maxPerformance = performance[i];
maxPerformanceIdx = i;
}
}

mPerformanceRank[maxPerformanceIdx] = performanceRank;
performance[maxPerformanceIdx] = 0;
}
}

IndexRange EGSScheduler::getWork(const size_t deviceGroup)
{
IndexRange work = mTasks[mPerformanceRank[deviceGroup]];

//Move the rest of the tasks up in line
for(size_t curTask = mPerformanceRank[deviceGroup];
curTask < mTasks.size() - 1;
curTask++)
{
mTasks[curTask] = mTasks[curTask + 1];
}

//Replace the last task if work remains
if(mNextIteration <= mEnd)
{
size_t count = (mEnd - mNextIteration + 1) / Device::GetDevices().size();
IndexRange newWork;

count = count == 0 ? 1 : count;

newWork.Start = mNextIteration;
newWork.End = mNextIteration + count - 1;

mNextIteration = newWork.End + 1;

mTasks[mTasks.size() - 1] = newWork;
}
else
{
size_t lastTrueIdx = mTasksValid.size() - 1;

while(1)
{
if(lastTrueIdx == 0)
{
mTasksValid[lastTrueIdx] = false;
break;
}

if(mTasksValid[lastTrueIdx] == true)
{
mTasksValid[lastTrueIdx] = false;
break;
}

lastTrueIdx--;
}
}

return work;
}

void EGSScheduler::setRange(IndexRange& range)
{
IScheduler::setRange(range);

size_t end = range.Start;
size_t remaining = range.End - range.Start + 1;
size_t numDevices = Device::GetDevices().size();

//Assign initial work
for(unsigned int curWorkIdx = 0; curWorkIdx < mTasks.size(); curWorkIdx++)
{
IndexRange work;
size_t count = remaining / numDevices;
count = count == 0 ? 1 : count;

work.Start = end;
work.End = work.Start + count - 1;

mTasks[curWorkIdx] = work;
mTasksValid[curWorkIdx] = true;

end = work.End + 1;

remaining = range.End - end + 1;

if(end > range.End)
{
break;
}
}

mNextIteration = end;
}

void EGSScheduler::updateModel(const DeviceStatus& status)
{
}

bool EGSScheduler::workRemains(size_t deviceGroup) const
{
return mTasksValid[mPerformanceRank[deviceGroup]];
}
18 changes: 10 additions & 8 deletions examples/DeviceInfo/DeviceInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@ int main(int argc, char** argv)
Device::FetchDevices();
size_t curDeviceNum = 0;

const vector<Device>& devices = Device::GetDevices();

for(size_t currentDevice = 0;
currentDevice < Device::GetDevices().size();
currentDevice++)
{
const Device& curDevice = Device::GetDevices()[currentDevice];
const DeviceInfo& deviceInfo = curDevice.getDeviceInfo();

cout << "Device " << curDeviceNum++ << endl;
cout << "\tName:" << devices[currentDevice].getDeviceInfo().Name << endl;
cout << "\tVendor:" << devices[currentDevice].getDeviceInfo().Vendor << endl;
cout << "\tDriver:" << devices[currentDevice].getDeviceInfo().DriverVersion << endl;
cout << "\tProfile:" << devices[currentDevice].getDeviceInfo().OpenCLProfile << endl;
cout << "\tVersion:" << devices[currentDevice].getDeviceInfo().OpenCLVersion << endl;
cout << "\tCVersion:" << devices[currentDevice].getDeviceInfo().OpenCLCVersion << endl;
cout << "\tName:" << deviceInfo.Name << endl;
cout << "\tVendor:" << deviceInfo.Vendor << endl;
cout << "\tDriver:" << deviceInfo.DriverVersion << endl;
cout << "\tProfile:" << deviceInfo.OpenCLProfile << endl;
cout << "\tVersion:" << deviceInfo.OpenCLVersion << endl;
cout << "\tCVersion:" << deviceInfo.OpenCLCVersion << endl;
cout << "\tNum Compute Units:" << deviceInfo.MaxComputeUnits << endl;
cout << "\tMax Frequency:" << deviceInfo.MaxClockFrequency << endl;
}

return 0;
Expand Down
11 changes: 9 additions & 2 deletions examples/ParallelFor/ParallelFor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ int main(int argc, char** argv)

Device::InitializeDevices(filename, 1);

Device::StartProfiling();

ParallelFor(0, 1, kBigArraySize, [&](size_t startIdx, size_t endIdx)
{
#if 1
#if 0
cout << "Device " << Device::GetCurrentDeviceNum()
<< " Start " << startIdx
<< " End " << endIdx << endl;
#else
unsigned int indexCount = endIdx - startIdx + 1;

Buffer aDevice(sizeof(a[0]) * indexCount);
Expand All @@ -44,7 +50,8 @@ int main(int argc, char** argv)

cDevice.get(&c[startIdx]);
#endif
});
},
EGSScheduler());

Device::DumpProfilingData();

Expand Down

0 comments on commit 509cc64

Please sign in to comment.