WEB开发网
开发学院软件开发VC 优化增强您的Visual C++应用程序 阅读

优化增强您的Visual C++应用程序

 2010-07-01 20:43:10 来源:WEB开发网   
核心提示:C++ InteropC++ interop 是用于本机托管 interop 的一种技术,它允许标准 C++ 代码带 /clr 开关编译,优化增强您的Visual C++应用程序(3),以便直接调用本机函数,而不用编程人员添加其他任何代码,这种类型的优化所节省的成本相当大,在这个示例中,当使用 /clr 开关时生成的代

C++ Interop

C++ interop 是用于本机托管 interop 的一种技术,它允许标准 C++ 代码带 /clr 开关编译,以便直接调用本机函数,而不用编程人员添加其他任何代码。当使用 /clr 开关时生成的代码是 MSIL(除了少数特例),并且数据可以是托管或非托管的(由用户指定数据的存放位置)。我倾向认为 C++ interop 是没有人知道的最重要的 .NET 功能。它是真正具有突破性的改革,但要真正了解 C++ interop 的强大之处还需要一定的时间。

在其他与 .NET 兼容的语言中,要与本机代码进行 interop 需要您将本机代码放在一个 DLL 中,并使用 dllimport 调用带有显式 P/Invoke 的函数(或者其他一些与此类似的做法,取决于您使用的语言)。否则就必须使用笨重的 COM interop 访问本机代码。这明显不方便,而且经常会遇到性能比 C++ 差很多的情况。

一般不认为 C++ interop 是 C++ 语言的性能特征,但正如您将看到的,C++ interop 所提供的灵活性和便利性却可以让您借助 CLR 获得更好的性能。

单映像中的本机代码和托管代码

Visual C++ 可以使编程人员(按逐函数方式)有选择地选择哪些函数是托管的,哪些是本机的。 这是通过 #pragma managed 和 #pragma unmanaged 实现的,图 3 显示了其中一个例子。在许多计算量大的任务中,让核心函数进行本机编译而其他代码进行托管编译可以带来很大好处。在单个映像中,C++ 可以将托管代码和本机代码混合一起,通过本机函数调用托管函数(反之亦然)不需要特殊的语法。在这种粒度下,C++ 可以很轻松地控制从托管代码向本机代码的转换,反之亦然。

当从托管代码向本机代码转换(或反向)时,执行的过程要经过由编译器/链接器生成的 thunk。这个 thunk 需要一定代价,编程人员都竭力避免付出这样的代价。有大量工作是在 CLR 中完成的,并且编译器会使转换的成本降到最低,但开发人员也可以通过降低这种转换的频率来帮助降低成本。

图 4 的 A 部分中是一个 C++ 应用程序,它的部分代码 (Z.cpp) 经编译生成 MSIL (/clr),而其他部分(X.cpp 和 Y.cpp)经编译生成本机代码。在这个程序中,Y.cpp 和 Z.cpp 中有些函数经过来回多次调用。这会导致大量托管/本机转换,从而降低程序的执行速度。

更改托管界限

图 4 更改托管界限

图 4 中的 B 部分显示了如何优化该程序来使托管/本机转换降至最少。其思想是确定常用接口,将它们都移到托管/本机界限的一侧,从而消除所有跨常用接口的转换。使用 Visual C++ 为 interop 提供的工具可以很轻松地完成这项工作。

例如,要从图 4 中的 A 转到 B,只需要用 /clr 开关重新编译 Y.cpp。现在 Y.cpp 被编译为托管代码,从 Z.cpp 调用就不需要有从托管到本机的转换成本。当然,您也需要考虑从 Y.cpp 生成 MSIL 的相关性能代价,并确保这种折衷对应用程序有利。

高性能封送处理

封送处理是托管/本机 interop 中成本最高的方面之一。在 C# 和 Visual Basic .NET 等语言中,封送处理是在调用 P/Invoke 时 CLR 隐式完成的(使用默认封送拆收器或者在实现 IcustomMarshaler 时用自定义封送处理代码完成)。而在 C++ interop 中,编程人员可以在代码中认为合适的地方显式封送处理数据。这样做的好处是编程人员可以一次性将数据封送到本机数据,然后通过多次调用重用数据的封送处理结果,从而均摊封送处理成本。

图 5 显示了带 /clr 开关编译的代码片段。在这段代码中有一个 for 循环,在这个循环中调用本机函数 (GetChar)。在图 6 中,采用 C# 实现相同的代码,并且通过调用 GetChar 来使 CsharpType 类封送处理到 NativeType,如下所示:

以下是引用片段:
   class NATIVECODE_API NativeType {
  public:
  NativeType();
  int pos;
  int length;
  char *theString;
  };

在 C++ 中,用户显式使用本机类型,因此不需要隐式封送。这种类型的优化所节省的成本相当大。在这个示例中,C++ 实现比 C# 实现快 18 倍。

上一页  1 2 3 4 5  下一页

Tags:优化 Visual

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接