Enumerable.Sum이 일부 입력에 대해 새로운 OverflowException을 throw함
.NET 8은 해당하는 경우 Enumerable.Sum 메서드에서 벡터화 지원을 추가합니다. 이러한 변경의 부작용으로 벡터화된 구현은 다른 요소가 추가되는 순서를 변경할 수 있습니다. 이로 인해 성공적인 실행의 최종 결과가 변경되지는 않지만, 병리적 입력 세트에 대해 예기치 않은 OverflowException 예외가 발생할 수 있습니다.
이전 동작
다음 코드를 생각해 봅시다.
Test(GetEnumerable1()); // Non-vectorizable
Test(GetEnumerable1().ToArray()); // Vectorizable
Test(GetEnumerable2()); // Non-vectorizable
Test(GetEnumerable2().ToArray()); // Vectorizable
static IEnumerable<int> GetEnumerable1()
{
for (int i = 0; i < 32; ++i)
{
yield return 1_000_000_000;
yield return -1_000_000_000;
}
}
static IEnumerable<int> GetEnumerable2()
{
for (int i = 0; i < 32; ++i)
{
yield return 100_000_000;
}
for (int i = 0; i < 32; ++i)
{
yield return -100_000_000;
}
}
static void Test(IEnumerable<int> input)
{
try
{
Console.WriteLine(input.Sum());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name);
}
}
이 변경 전에는 이전 코드가 다음과 같은 출력을 인쇄했습니다:
0
0
OverflowException
OverflowException
새 동작
.NET 8부터 이전 동작 섹션의 코드 조각은 다음 출력을 인쇄합니다.
0
OverflowException
OverflowException
0
도입된 버전
.NET 8 미리 보기 7
호환성이 손상되는 변경의 형식
이 변경 사항은 동작 변경입니다.
변경 이유
이 변경 내용은 LINQ API의 벡터화를 활용하기 위해 수행되었습니다.
권장 작업
코드가 변경의 영향을 받는 경우 다음 중 하나를 수행할 수 있습니다.
DOTNET_EnableHWIntrinsic
환경 변수를 0으로 설정하여 애플리케이션에서 벡터화를 모두 사용하지 않도록 설정합니다.벡터화를 사용하지 않는 사용자 지정
Sum
메서드를 작성합니다.static int Sum(IEnumerable<int> values) { int acc = 0; foreach (int value in values) { checked { acc += value; } } return acc; }
영향을 받는 API
GitHub에서 Microsoft와 공동 작업
이 콘텐츠의 원본은 GitHub에서 찾을 수 있으며, 여기서 문제와 끌어오기 요청을 만들고 검토할 수도 있습니다. 자세한 내용은 참여자 가이드를 참조하세요.
.NET