Bloqueio Singleton com verificação dupla em C ++ 11

A seguinte implementação de singleton é livre de corrida?

static std::atomic<Tp *> m_instance;
...

static Tp &
instance()
{
    if (!m_instance.load(std::memory_order_relaxed))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!m_instance.load(std::memory_order_acquire))
        {
            Tp * i = new Tp;
            m_instance.store(i, std::memory_order_release);    
        }    
    }

    return * m_instance.load(std::memory_order_relaxed);
}

É ostd::memory_model_acquire da operação de carregamento supérfluo? É possível relaxar ainda mais as operações de carregamento e armazenamento, alternando-as parastd::memory_order_relaxed? Nesse caso, é a semântica de aquisição / liberação destd::mutex o suficiente para garantir sua correção, ou maisstd::atomic_thread_fence(std::memory_order_release) também é necessário para garantir que as gravações na memória do construtor ocorram antes da loja relaxada? No entanto, o uso de cerca é equivalente a ter a loja commemory_order_release?

EDITA: Graças à resposta de John, eu vim com a seguinte implementação que deve ser livre de corrida de dados. Mesmo que a carga interna possa ser atômica, decidi deixar uma carga relaxada, pois ela não afeta o desempenho. Em comparação a sempre ter uma carga externa com a ordem de aquisição de memória, o mecanismo thread_local melhora o desempenho de acessar a instância de aproximadamente uma ordem de magnitud

static Tp &
instance()
{
    static thread_local Tp *instance;

    if (!instance && 
        !(instance = m_instance.load(std::memory_order_acquire)))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!(instance = m_instance.load(std::memory_order_relaxed)))
        {
            instance = new Tp; 
            m_instance.store(instance, std::memory_order_release);    
        }    
    }
    return *instance;
}

questionAnswers(3)

yourAnswerToTheQuestion