考虑从更复杂的代码中提取的以下示例:
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <map>
#include <string>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
// The class implements a XML tag storing the name and a variable number of attributes:
struct Tag
{
// The typedef defines the type used for a XML name:
typedef std::string name_type;
// The typedef defines the type used for a XML value:
typedef std::string value_type;
// The typedef defines the type of a XML attribute: …Run Code Online (Sandbox Code Playgroud) 根据我之前的问题,我的想法是在系数m_a,m_b为1.0或0.0时通过去除计算来优化算法.现在我尝试优化算法并得到一些我无法解释的奇怪结果.
第一个分析仪运行100k样品.从文件(!)读取参数值:
b0 = 1.0 b1 = -1.480838022915731 b2 = 1.0
a0 = 1.0 a1 = -1.784147570544337 a2 = 0.854309980957510

第二个分析仪运行相同的100k样本.从文件(!)读取参数值:
b0 = 1.0 b1 = -1.480838022915731 b2 = 1.0
a0 = 1.0 a1 = -1.784147570544337 a2 = 0.0 <---只有a2不同!

在图中,左侧的数字(灰色背景)表示所需的CPU周期.因为参数a2 = 0.0的清晰可见的第二次运行要快得多.
我检查了调试和发布代码之间的区别.发布代码更快(正如预期的那样).修改参数a2时,调试和释放代码具有相同的奇怪行为.
然后我检查了ASM代码.我注意到使用了SSE指令.这是有效的,因为我用/ arch:SSE2编译.因此我禁用了SSE.生成的代码不再使用SSE,性能不再依赖于参数值a2(如预期的那样)
因此,我得出的结论是,当使用SSE并且SSE引擎检测到a2为0.0时,它们是某种性能优势,因此省略了过时的乘法和减法.我从来没有听说过这个,并试图找到信息,但没有成功.
那么有人对我的表现结果有解释吗?
为完整起见,这是发布版本的相关ASM代码:
00F43EC0 mov edx,dword ptr [ebx]
00F43EC2 movss xmm0,dword ptr [eax+edi*4]
00F43EC7 cmp edx,dword ptr [ebx+4]
00F43ECA je $LN419+193h (0F43F9Dh)
00F43ED0 mov esi,dword ptr [ebx+4]
00F43ED3 lea eax,[edx+68h]
00F43ED6 lea …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
namespace qi = boost::spirit::qi;
typedef qi::rule<
std::string::const_iterator
> rule_type;
rule_type value_rule = +qi::char_ - ( '[' | qi::eoi );
std::string input( "Hello World" );
std::string value0, value1;
bool b0 = qi::parse( input.begin( ),
input.end( ),
value_rule,
value0 );
bool b1 = qi::parse( input.begin( ),
input.end( ),
+qi::char_ - ( '[' | qi::eoi ),
value1 );
Run Code Online (Sandbox Code Playgroud)
结果:
b0 = true
b1 = true
value0 = ""
value1 = "Hello World"
Run Code Online (Sandbox Code Playgroud)
我很困惑为什么结果不同.为获得相同的结果,qi :: rule类型的正确定义是什么?
假设以下虚拟模板:
template < class DataType > class Dummy
{
public:
void init( )
{
m_data = DataType( 0 );
}
private:
DataType m_data;
};
Run Code Online (Sandbox Code Playgroud)
调用init将初始化内部数据.当DataType是标准数据类型(例如int或float)时,这确实可以正常工作.当DataType是一个类时,该类必须具有相应的构造函数.
现在假设DataType应该是例如由合适的类表示的复数.在这种情况下,为复数类提供一个带有一个参数的构造函数是没有意义的,因为在正常条件下,您需要初始化实部和虚部.
所以我的问题是:在考虑模板适合存储任何数据类型的情况下,初始化模板类型的最佳通用方法是什么.
我认为例如STL必须实现这样的思考,但我在该代码中迷失了.