gpt4 book ai didi

C# 64 位版本构建在没有调试的情况下启动时的行为与在调试时启动时的行为不同 (BigInteger)

转载 作者:太空狗 更新时间:2023-10-29 17:45:59 25 4
gpt4 key购买 nike

我是 C# 的新手,遇到了以下代码的问题(我的目标框架是 4.5,我添加了对 System.Numerics 的引用):

using System;
using System.Numerics;

namespace Test
{
class Program
{
static BigInteger Gcd(BigInteger x, BigInteger y)
{
Console.WriteLine("GCD {0}, {1}", x, y);
if (x < y) return Gcd(y, x);
if (x % y == 0) return y;
return Gcd(y, x % y);
}

static void Main(string[] args)
{
BigInteger a = 13394673;
BigInteger b = 53578691;
Gcd(a, b);
}
}
}

当发布版本开始调试时(Visual Studio 中的 F5 - 以及程序末尾的断点,以便我可以看到输出),我得到以下输出:

GCD 13394673, 53578691
GCD 53578691, 13394673
GCD 13394673, 13394672
GCD 13394672, 1

但是,当在没有调试 (Ctrl-F5) 的情况下启动发布构建时,我得到以下信息:

GCD 13394673, 53578691
GCD 53578691, 53578691

奇怪的是,如果我在程序末尾添加一个 Console.ReadLine(),它会按预期工作!

知道是什么原因造成的吗?谢谢。

最佳答案

这是 .NET 4.0 到 4.5.2 中的 x64 抖动优化器错误。表征它相当困难,由于 BigInteger 的使用,代码生成非常繁重。 x64 抖动在 struct 类型(如 BigInteger)的优化器错误历史上一直存在,因此这可能是根本原因。与此方法中可能的尾调用优化的组合是最有可能的触发器。

我通常会建议报告这样的错误,但这种紧张的日子已经屈指可数了。 Microsoft 决定淘汰它并完全重写它。在 .NET 4.6 - VS2015 中可用,项目代号为 RyuJIT。它没有这个错误。

几种可能的解决方法:

项目 + 属性,构建选项卡,平台目标 = x86。这会强制程序以 32 位模式运行并使用 x86 抖动,它没有这个错误。

或者使用属性禁用此方法的优化:

  using System.Runtime.CompilerServices;
...
[MethodImpl(MethodImplOptions.NoOptimization)]
static BigInteger Gcd(BigInteger x, BigInteger y) {
// etc...
}

没关系,BigInteger 类中的繁重工作因此禁用优化不会影响执行时间。

关于C# 64 位版本构建在没有调试的情况下启动时的行为与在调试时启动时的行为不同 (BigInteger),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31137448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com