c++ - 用模板结构中的静态 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
。
好的,所以我的主要问题是这将如何影响性能?我应该期待大量开销吗?我应该期待任何开销吗?编译器优化是否会因此而保持沉默?
欢迎任何意见。
解决方案
推荐阅读
- javascript - 在最后一个参数上获取带有增量号的 api 请求
- ios - 尝试呈现其视图不在窗口层次结构中的 Xamarin_Forms_Platform_iOS_NavigationRenderer
- javascript - React - 如何取消过滤。()我的对象数组?
- java - 无法从通知中打开活动
- reactjs - 从库导入时,Invariant 失败:您不应该使用
外面 - mysql - mysql更新列,来自2个表的值
- ruby-on-rails - 使用 Postgresql 函数的 Rails change_column 迁移 - 时间到整数(自午夜以来的秒数)
- google-analytics - 在 BigQuery 中按命中范围的自定义维度计算会话、用户和收入
- html - 24 英寸和 32 英寸显示器对应的像素大小是多少?
- java - 用流替换 for 循环