Use std::call_once to construct singeltons

By using `call_once` from C++11, we can simplify the logic in code
where we are querying same value variables from multiple threads.
This commit is contained in:
Haocheng LIU 2018-08-06 15:25:03 -04:00
parent c00bf941a5
commit ce9cd8072a
3 changed files with 34 additions and 31 deletions

@ -0,0 +1,4 @@
# Use std::call_once to construct singeltons
By using call_once from C++11, we can simplify the logic in code where we are querying same value variables from multiple threads.

@ -41,15 +41,10 @@ VTKM_CONT_EXPORT vtkm::UInt32 getNumSMs(int dId)
}
//check
static bool lookupBuilt = false;
static std::once_flag lookupBuiltFlag;
static std::vector<vtkm::UInt32> numSMs;
if (!lookupBuilt)
{
//lock the mutex
static std::mutex built_mutex;
std::lock_guard<std::mutex> lock(built_mutex);
std::call_once(lookupBuiltFlag, []() {
//iterate over all devices
int numberOfSMs = 0;
int count = 0;
@ -61,8 +56,7 @@ VTKM_CONT_EXPORT vtkm::UInt32 getNumSMs(int dId)
cudaDeviceGetAttribute(&numberOfSMs, cudaDevAttrMultiProcessorCount, deviceId));
numSMs.push_back(static_cast<vtkm::UInt32>(numberOfSMs));
}
lookupBuilt = true;
}
});
return numSMs[index];
}
}

@ -21,6 +21,8 @@
#ifdef VTKM_CUDA
#include <mutex>
#include <cuda.h>
#include <vtkm/Math.h>
#include <vtkm/cont/cuda/ErrorCuda.h>
@ -43,27 +45,15 @@ static __global__ void DetermineIfValidCudaDevice()
}
}
}
#endif
namespace vtkm
namespace
{
namespace cont
static std::once_flag deviceQueryFlag;
static int numDevices = 0;
static int archVersion = 0;
void queryNumberOfDevicesandHighestArchSupported(vtkm::Int32& nod, vtkm::Int32& has)
{
DeviceAdapterRuntimeDetector<vtkm::cont::DeviceAdapterTagCuda>::DeviceAdapterRuntimeDetector()
: NumberOfDevices(0)
, HighestArchSupported(0)
{
#ifdef VTKM_CUDA
static bool deviceQueryInit = false;
static int numDevices = 0;
static int archVersion = 0;
if (!deviceQueryInit)
{
deviceQueryInit = true;
std::call_once(deviceQueryFlag, []() {
//first query for the number of devices
auto res = cudaGetDeviceCount(&numDevices);
if (res != cudaSuccess)
@ -98,10 +88,25 @@ DeviceAdapterRuntimeDetector<vtkm::cont::DeviceAdapterTagCuda>::DeviceAdapterRun
archVersion = 0;
}
}
}
});
nod = numDevices;
has = archVersion;
}
} // anonymous namspace
this->NumberOfDevices = numDevices;
this->HighestArchSupported = archVersion;
#endif
namespace vtkm
{
namespace cont
{
DeviceAdapterRuntimeDetector<vtkm::cont::DeviceAdapterTagCuda>::DeviceAdapterRuntimeDetector()
: NumberOfDevices(0)
, HighestArchSupported(0)
{
#ifdef VTKM_CUDA
queryNumberOfDevicesandHighestArchSupported(this->NumberOfDevices, this->HighestArchSupported);
#endif
}