使用单例对象时,有没有办法防止缓存未命中?这是我目前的单例实现:
SingletonObject.h
#pragma once
class SingletonObject
{
public:
static SingletonObject* SingletonObject();
static void SingletonObject();
private:
static SingletonObject* sSingletonObject;
SingletonObject();
~SingletonObject();
};
SingletonObject.cpp
#include "SingletonObject.h"
SingletonObject* SingletonObject::sSingletonObject = NULL;
SingletonObject:: SingletonObject()
{
}
SingletonObject::~ SingletonObject()
{
}
SingletonObject* SingletonObject::GetSingleton()
{
if (sSingletonObject == NULL) // cache miss
{
sSingletonObject = new SingletonObject();
}
return sSingletonObject;
}
void SingletonObject::DestroySingleton()
{
delete sSingletonObject;
sSingletonObject = NULL;
}
有没有更好的方法可以防止缓存丢失?这只是不使用单身人士的另一个原因吗?
更新:事实证明它与缓存无关,就像为堆栈展开生成的代码和GetSingleton()调用中的条件检查一样。通过显式创建和销毁单例(而不是创建它的需求),并为静态实例创建一个访问器,我能够避免大量的开销,并注意到分析的显着加速。
SingletonObject.h
#pragma once
class SingletonObject {
public:
static void CreateSingleton();
static void DestroySingleton();
static inline SingletonObject* GetSingleton() { return sInstance; }
private:
static SingletonObject* sInstance;
SingletonObject();
}
SingletonObject.cpp
#include "SingletonObject.h"
void SingletonObject::CreateSingleton() {
if (sInstance == NULL)
sInstance = new SingletonObject();`
}
void SingletonObject::DestroySingleton() {
delete(sInstance);
sInstance = NULL;
}
答案 0 :(得分:1)
不,在整个程序中没有更多的知识,即将出现对单例指针的引用,然后它可以使用指针和它将引用的对象来启动L1 / L2高速缓存。
这种技术称为预取。
答案 1 :(得分:1)
这是人们在性能优化之路上走下去的一个非常具体的问题。你确定你一直都在那里吗?原因我问的是,如果你经常访问你的Singleton,指向对象的指针将保留在缓存中。如果它不在缓存中,那么你就不会经常访问该对象,这意味着你并不真正需要它,因此将指针(或对象)预取到缓存只会从你所拥有的东西中窃取宝贵的缓存空间在现实中经常使用 - 从长远来看,这甚至可能会损害性能。 根据我的理解,你现在遇到的问题是你必须完成以下步骤:
static SingletonObject* SingletonObject();
功能确实是一个热点(>总时间的10%用于执行此功能)static SingletonObject* SingletonObject();
之间访问的数据量,并检查是否所有这些访问都是必需的。如果它们是,那么这是一个合理的缓存未命中,你无法做任何事情。如果不是,请尽可能减少工作量并重新运行探查器(步骤2)。_mm_prefetch()
次调用访问Singleton对象。