c++ - 在通用对象更新循环中,按 Controller 更新还是按对象更新更好?

标签 c++ performance templates c++11

我正在编写一些通用代码,它基本上将包含一个由一组 Controller 更新的对象 vector 。

代码在我的特定上下文中有点复杂,但可以简化为:

template< class T >
class Controller
{ 
public:
    virtual ~Controller(){}
    virtual void update( T& ) = 0;
    // and potentially other functions used in other cases than update
}

template< class T >
class Group
{
public:
    typedef std::shared_ptr< Controller<T> > ControllerPtr;

    void add_controller( ControllerPtr );    // register a controller
    void remove_controller( ControllerPtr ); // remove a controller

    void update(); // udpate all objects using controllers

private:

    std::vector< T > m_objects;
    std::vector< ControllerPtr > m_controllers;
};

我故意不使用 std::function 因为我不能在我的特定情况下使用它。 我也有意使用共享指针而不是原始指针,这实际上对我的问题并不重要。

无论如何,我感兴趣的是 update() 实现。 我可以通过两种方式做到这一点。

A) 对于每个 Controller ,更新所有对象。

template< class T >
void Group<T>::update()
{
    for( auto& controller : m_controllers )
        for( auto& object : m_objects )
            controller->update( object );
}

B) 对于每个对象,通过应用所有 Controller 进行更新。

template< class T >
void Group<T>::update()
{
    for( auto& object : m_objects )
        for( auto& controller : m_controllers )
            controller->update( object );
}

“测量!测量!测量!” 你会说,我完全同意,但我无法测量我不使用的东西。问题是它是通用代码。我不知道T的大小,我只是假设它不会很大,也许很小,也许还是有点大。真的,除了 T 被设计为包含在 vector 中之外,我不能对 T 做太多假设。 我也不知道将使用多少 Controller 或 T 实例。在我当前的用例中,计数会有很大不同。

问题是:哪种解决方案通常最有效?

我在这里考虑缓存一致性。此外,我假设此代码将用于不同的编译器和平台。

我的直觉告诉我,更新指令缓存肯定比更新数据缓存更快,这将使解决方案 B) 通常更有效。但是,当我对性能有疑问时,我学会了不相信自己的阵风,所以我在这里问。

我得到的解决方案将允许用户选择(使用编译时策略)哪个更新实现与每个 Group 实例一起使用,但我想提供一个默认策略,但我无法决定哪个对于大多数情况,这将是最有效的。

最佳答案

我们有现代编译器(尤其是 Intel C++)能够交换循环的活生生的证据,所以这对您来说应该无关紧要。

我从伟大的@Mysticial's answer中记住了它:

Intel Compiler 11 does something miraculous. It interchanges the two loops, thereby hoisting the unpredictable branch to the outer loop. So not only is it immune the mispredictions, it is also twice as fast as whatever VC++ and GCC can generate!

Wikipedia article about the topic

检测是否可以进行循环交换需要检查交换后的代码是否真的会产生相同的结果。从理论上讲,可以准备不允许交换的类,但话又说回来,可以准备可以从任一版本中获益更多的类。

关于c++ - 在通用对象更新循环中,按 Controller 更新还是按对象更新更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15844412/

相关文章:

c++ - opencv图像去噪头文件

c++ - MSDN 示例 : The Open Dialog Box Not Compiling

c++ - linux mint 进程中的代码块以状态 -1 终止

使用 Order By 时 MySQL 查询变得非常慢

android - 在 android 中找到距离 db 最近的 25 个地方很慢

java - 新 TLAB 中的分配与 TLAB 之外的分配

python - 获取模板中所有自定义用户的列表(Django)

c++ - 如何避免 cin.operator>> 和 getline 之间的冲突?

c++模板化 map ,不同类型参数的通用接口(interface)

c++ - 模板函数的奇怪输出的解释