在C ++中预热一些变量

时间:2013-04-05 07:41:07

标签: c++ data-structures

我有一个可以处理某些数值的C ++库,这些值在编译时不可用,但在运行时立即可用,并且基于机器相关的细节,简而言之我需要显示分辨率,数量等值CPU核心等。

我的问题的关键点是:

  • 我不能要求用户输入这个值(我的lib和最终用户的编码器/用户)
  • 我只需要在应用程序启动后进行预热,这只是一次性的事情
  • 此值稍后由方法和类
  • 使用

可能的解决方案是:

  • 构建数据结构Data,声明一些Data dummy,其中dummy是用于存储所有内容的变量的名称,而构造函数将处理相关的一次性inizialization值
  • 在类似WarmUp()的方法中包装类似于第一个解决方案的东西,并在main()开始之后立即使用此方法(这也是一个记住和使用的简单方法)

尚未解决的重大问题是:

  • 用户可以声明多个数据结构,因为Data它是一个类型,并且对于在C ++中抛出相同类型的2-4-5-17变量没有限制
  • WarmUp()方法在其他类的设计中可能有点干扰,也可能发生WarmUp()方法用于本地方法而不是main()

我基本上需要在运行时强制创建1个特定类型的1个实例,因为我对我的库的实际使用没有任何影响,或者至少我需要以用户将立即理解的方式设计它什么样的错误使得尽可能直观和简单地使用库。

你能看到解决方案吗?


修改

由于我也在尝试获得兼容多线程的数据结构,因此我的问题也更加困难。

3 个答案:

答案 0 :(得分:2)

如何使用lazily-create singleton? E.g

struct Data
{
  static Data & instance()
  {
    static Data data_;
    return data_;
  }
private:
  Data()
  {
    //init
  }
}
当您致电Data

时,

Data::instance()会在首次使用时初始化

编辑:与多线程一样,请阅读efficient thread-safe singleton in C++

使用boost :: call_once

Edit2 realisation

答案 1 :(得分:0)

预热通常与性能问题有关(并让我想到处理器缓存,请参阅GCC的__builtin_prefetch)。

也许你想制作一个singleton class,有很多解决方法(例如this C++ singleton tutorial)。

此外,如果性能是主要考虑因素,您可以考虑在初始化(甚至在安装时)给出配置的参数。然后,您可以专门化您的代码,可能就像拥有模板一样简单,并通过发出(在运行时=初始化时)相应的C ++存根源代码并编译它(在“运行时”,例如在初始化时)和{{ 3}}它(使用插件& dlopen ...)。另请参阅dynamically loading

答案 2 :(得分:0)

首先,正如其他人所说的那样,明显(和最好)的答案 这是一个单身人士。既然你已经添加了多线程 但要求:有两种解决方案,具体取决于 是否使用单例代码修改对象。 (根据你的描述,我没有收集。)如果不是,那就是 足以使用单身的“天真”实现,和 确保在线程之前初始化单例 开始。如果在输入main之前没有启动任何线程(和 我会认为这是不好的做法),然后像 以下内容基本上足够了:

class Singleton
{
    static Singleton const* ourInstance;
    Singleton();

    Singleton( Singleton const& );
    Singleton& operator=( Singleton const& );

public:
    static Singleton const& instance();
};

并在实施中:

Singleton const* Singleton::ourInstance = &Singleton::instance();

Singleton const&
Singleton::instance()
{
    if ( ourInstance == NULL ) {
        ourInstance = new Singleton;
    }
    return *ourInstance;
}

不需要锁定,因为没有线程会被修改 任何线程开始的任何事情。

如果单例是可变的,那么你必须保护所有访问权限 它。你可以做类似上面的事情(没有 显然是const,并将锁定留给客户端,但是 在这种情况下,我更喜欢锁定instance函数,并且 使用删除器返回std::shared_ptr以释放 锁定,是在instance函数中获取的。我认为 类似下面的东西可以工作(但我从来没有 需要它,所以没有尝试过):

class Singleton
{
    static Singleton* ourInstance;
    static std::mutex ourMutex;

    class LockForPointer
    {
    public:
        operator()( Singleton* )
        {
            Singleton::ourMutex.unlock();
        }
    };
    class LockForInstance
    {
        bool myOwnershipIsTransfered;
    public:
        LockForInstance
            : myOwnershipIsTransfered( false )
        {
            Singleton::ourMutex.lock();
        }
        ~LockForInstance()
        {
            if ( !myOwnershipIsTransfered ) {
                Singleton::ourMutex.unlock();
            }
        }
        LockForPointer transferOwnership()
        {
            myOwnershipIsTransfered = true;
            return LockForPointer();
        }
    };
public:
    static std::shared_ptr<Singleton> instance();
};

和实施:

static Singleton* ourInstance = NULL;
static std::mutex ourMutex;

std::shared_ptr<Singleton>
Singleton::instance()
{
    LockForInstance lock;
    if ( ourInstance == NULL ) {
        ourInstance = new Singleton;
    }
    return std::shared_ptr<Singleton>( ourInstance, lock.transferOwnership() );
}

这样,相同的锁用于检查null和for 访问数据。