引用英特尔 ®64 和IA-32架构优化参考手册,§2.4.6"REP String Enhancement":
使用REP字符串的性能特征可归因于两个组件: 启动开销和数据传输吞吐量.
[...]
对于较大粒度数据传输的REP字符串,随着ECX值的增加,REP String的启动开销呈逐步增加:
- 短串(ECX <= 12):REP MOVSW/MOVSD/MOVSQ的延迟约为20个周期,
快速字符串(ECX> = 76:不包括REP MOVSB):处理器实现通过移动尽可能多的16字节数据来提供硬件优化.如果其中一个16字节数据传输跨越缓存行边界,则REP字符串延迟的延迟会有所不同:
- 无拆分:延迟包括大约40个周期的启动成本,每个64字节的数据增加4个周期,
- 高速缓存拆分:延迟包括大约35个周期的启动成本,每64个字节的数据增加6个周期.
中间字符串长度:REP MOVSW/MOVSD/MOVSQ的延迟具有大约15个周期的启动成本加上word/dword/qword中数据移动的每次迭代的一个周期.
(强调我的)
没有进一步提及这种启动成本.它是什么?它做了什么,为什么总是需要更多的时间?
最近,我给了一个答案到这个问题,如何让Python的像串的重复,如"hello" * 2给"hellohello".
我不会在这里重复定义,但函数声明是:
std::string repeat(std::string str, const std::size_t n);
Run Code Online (Sandbox Code Playgroud)
当然可以像:
std::cout << repeat("helloworld", 2) << std::endl;
Run Code Online (Sandbox Code Playgroud)
为了更接近Python版本,我想我会超载operator*.理想情况下,我使用通用引用来避免额外的std::string移动,但运算符必须使用用户定义的类型.所以我尝试了这个:
#include <type_traits> // std::enable_if_t, std::is_integral
#include <utility> // std::move
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
std::string operator*(std::string str, const T n)
{
return repeat(std::move(str), static_cast<std::size_t>(n));
}
Run Code Online (Sandbox Code Playgroud)
现在我可以这样做:
std::cout << (std::string("helloworld") * 2) << std::end;
Run Code Online (Sandbox Code Playgroud)
还有这个:
std::cout << operator*("helloworld", 2) << std::endl;
Run Code Online (Sandbox Code Playgroud)
但不是这个:
std::cout << ("helloworld" * 2) << …Run Code Online (Sandbox Code Playgroud) 是否存在等效的单行'#'*number,如果数字为4,那么表达式的输出是否为"####"C++?如果没有等效的单行,我想知道是否有任何快速方法可以做到这一点,不包括for循环.
注意:我正在使用C++ 14,在我正在使用的程序上我不能使用C++ 1z(17),所以没有C++ 1z的建议.
c++ ×2
assembly ×1
c++11 ×1
c++14 ×1
operators ×1
optimization ×1
performance ×1
python ×1
string ×1
x86 ×1