【问题标题】:Translating unmanaged C++ code to managed C++ for calling from C#将非托管 C++ 代码转换为托管 C++ 以便从 C# 调用
【发布时间】:2011-12-25 09:23:15
【问题描述】:

我有一些需要大量二进制操作的 C# 代码,因此我编写了一个非托管 C++ 方法来替换其中一个 C# 方法。令我震惊的是,它慢了 10 倍。我运行了一个配置文件,发现缓慢来自调用外部方法的开销,而不是方法本身。

所以我想如果我用托管 C++ 编写方法,我会减少调用的开销,但仍然有 C++ 的速度。首先,这个假设是否成立?

这是我的非托管 C++ 代码:

#include "stdafx.h";

unsigned __int32 _stdcall LSB_i32(unsigned __int32 x)
{
    DWORD result;
    _BitScanForward(&result, x);
    return (unsigned __int32)result;
}

这是我的 C# 代码:

public static partial class Binary
{
    [DllImport(@"CPP.dll")]
    public static extern int LSB_i32(int value);
}

我在这里做错了吗?

如何将上述内容转换为托管 C++?我对此进行了一些浏览,但是由于我对托管 C++ 不熟悉,所以我没有走多远。

【问题讨论】:

    标签: c++ .net visual-studio unmanaged managed


    【解决方案1】:

    您可以保留非托管方法,但不应经常从托管代码中调用它。例如,如果您在紧密循环中调用非托管方法,那么在托管代码和非托管代码之间进行封送处理的开销将是巨大的。因此,您可以尝试将此循环放在非托管代码中,以便仅对该方法执行一次调用。然后您只需支付一次封送处理费用,整个繁重工作将在非托管代码中完成。

    就将其转换为托管 C++ 而言,我非常怀疑这会给您带来比您开始使用的更好的东西(即完全托管的 C# 代码)。

    【讨论】:

    • 不幸的是,我不能将代码放入循环中,因为它是一个辅助函数。我正在做的 C++ 代码应该是其核心的单个 ASM 函数 (bsr),它应该比复杂的 C# 二进制操作快得多。如果没有别的,我想试试。
    • @IanC,在这种情况下,将其保留为完全托管的代码。它会运行得更快。
    • 您的意思是完全托管的 C# 代码?当然,如果它是托管的,我应该能够编写托管 C++ 并从中受益吗?
    • @IanC,不,恕我直言,您不会从托管 C++ 中受益。它在 CLR 中运行,您将获得与 C# 相似的性能。
    • 托管 C++ 是否具有常规 C++(如 SSE 和 ASM)的所有优点?
    【解决方案2】:

    如果纯 C# 实现更快,你可以试试:

    static int lzc(int x)
    {
        x |= (x >> 1);
        x |= (x >> 2);
        x |= (x >> 4);
        x |= (x >> 8);
        x |= (x >> 16);
    
        x = x - ((x >> 1) & 0x55555555);
        x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
        x = (x + (x >> 4)) & 0x0f0f0f0f;
        x = x + (x >> 8);
        x = x + (x >> 16);
        return 32 - (x & 0x0000003f);
    }
    

    【讨论】:

    • 谢谢。我在 C# 中有比这更快的实现。我想知道的是如何用托管C++编写上述代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    相关资源
    最近更新 更多