首页 > 解决方案 > 用模板结构中的静态 constexpr 成员替换宏的优化和性能损失(或缺乏)

问题描述

对正在发生的事情的简短描述:

目标是概括我拥有的一些代码。长话短说,有一个基类base管理std::array<unsigned long long,N_DIM_IDX>. 类建立在类建立,建立在类...建立在base。这些类有很多方法来检查设置位、移位和翻转位,以及计算base. std::array基本上扩展到超过 64 位集合。它是如何扩展和跟踪结束位置的,这些东西是由宏来处理的。

每次我需要重新运行时,我都需要更改宏。实际上我需要更改一个设置所有宏的宏。我无法改变,unsigned long long因为所有的簿记都是针对 64 位单元完成的,而且我ULL在几个地方都使用了文字。我正在考虑用static constexpr模板结构中的成员替换所有这些,并使其可以使用 anyunsigned作为构建块,而不仅仅是ull

这些是我正在考虑更换的:

using myuint = unsigned long long;

// Only reset this for new runs if needed:
#define BASE_DIM 120ULL

#define DIM 64ULL

#if BASE_DIM%DIM==0ULL

  #define N_DIM_IDX ((BASE_DIM)/(DIM))
  #define POS_LAST 63ULL
  #define POS_LAST_IDX (N_DIM_IDX - 1ULL)

#else

  #define N_DIM_IDX ( 1ULL + ((BASE_DIM)/(DIM)) )
  #define POS_LAST ((BASE_DIM%DIM) - 1ULL)
  #define POS_LAST_IDX (N_DIM_IDX - 1ULL)

#endif

这些现在嵌入在代码中无数的地方,在速度很重要的关键任务部分。以下是我正在考虑的替代品:

// size in bits. maybe change it as all platform don't necessarily have byte = 8 bits
template<typename U, std::enable_if_t<std::is_unsigned<U>::value, int> = 0 >
struct T_bit_size{
  typedef U type;
  static constexpr U value = sizeof(U)*8;
};

template<typename U, U D, typename E = void >
struct details{
  static constexpr bool value     = false;
  static constexpr bool divisible = false;
};

// all bookkeeping here
template<typename U, U D>
struct details<U,D,std::enable_if_t<std::is_unsigned<U>::value && (D>0) > >{
  static constexpr bool value     = true;
  static constexpr U dim          = D;                                         // Replaces BASE_DIM
  static constexpr U units        = T_bit_size<U>::value;                      // Replaces DIM 
  static constexpr bool divisible = (dim%units == 0);
  typedef U type;

  static constexpr U N_idx       = divisible ? (dim/units) : (dim/units + 1);  // Replaces N_DIM_IDX
  static constexpr U L_idx       = N_idx - 1;                                  // Replaces POS_LAST_IDX
  static constexpr U L_idx_N_pos = divisible ? (units) : (dim%units);          // New!!!
  static constexpr U L_idx_L_pos = L_idx_N_pos - 1;                            // Replaces POS_LAST
};

// one of type U
template<typename U>
struct unsigned_value_of{
  static constexpr U one  = 1;
};

作为代码中的一个示例,这就是我将如何替换它:

//     currently:
class something{
// stuff
/*1)*/ for(myuint k=0; k<=(POS_LAST_IDX); k++)
// stuff
/*2)*/ (stuff)&(1ULL << POS_LAST_IDX)
// stuff
};

//     if replaced:
template<typename U, U D > /* some enable_if for only unsigned enabled*/
class something{
// stuff
/*1)*/ for(U k=0; k<details<U>::N_idx; k++)
// stuff
/*2)*/ (stuff)&(unsigned_value_of<U>::one << details<U>::L_idx_L_pos)
// stuff
};

如果我这样做,可能需要两天的时间仔细更换并检查我没有刹车。如果我确实替换它,我有一个通用代码。如果有任何进一步的簿记发生,我可以添加另一个成员details

好的,所以我的主要问题是这将如何影响性能?我应该期待大量开销吗?我应该期待任何开销吗?编译器优化是否会因此而保持沉默?

欢迎任何意见。

标签: c++performanceoptimizationmacrosconstexpr

解决方案


推荐阅读