현대 게임 코드에서 어셈블리는 평균 얼마나 자주 사용됩니까?
특히 임베디드 시스템의 게임이 어셈블리를 광범위하게 사용한다고 가정하기 때문에 x86, PPC 또는 ARM과 같은 우수한 C ++ 컴파일러가있는 플랫폼에서 특히 그렇습니다.
현대 게임 코드에서 어셈블리는 평균 얼마나 자주 사용됩니까?
특히 임베디드 시스템의 게임이 어셈블리를 광범위하게 사용한다고 가정하기 때문에 x86, PPC 또는 ARM과 같은 우수한 C ++ 컴파일러가있는 플랫폼에서 특히 그렇습니다.
답변:
대답은 "게임"의 의미와 "사용 된"에 따라 다릅니다. "사용됨"은 "특정 게임 프로젝트 중에 작성 됨"을 의미한다고 가정하겠습니다.
내가 경험 한 사람들의 경험과 일화 데이터에서
게임 업계에서는 어셈블리 언어에 대한 지식이 필요하지 않지만, 만드는 게임 유형에 따라 유리할 수 있습니다.
컴파일러가 사람이 직접 작성한 어셈블리보다 C 코드를 최적화하는 데 더 나은 작업을한다는 주장이있었습니다. 보통은 사실이며 때로는 거짓입니다. 그러나 요즘 계속 증가하는 CPU 복잡성과 '확장'확장 (즉, 프로세서 분리)의 필요성은 최적화 노력이 일반적으로 다른 곳에 소비됨을 의미합니다.
최근 몇 년 동안 게임 코드에서 어셈블리를 본 유일한 시점은 __asm int 3
중단 점을 강요하는 진술뿐이었습니다. 개인적으로 어셈블리를 개인적으로 사용하는 경우 비정상적인 충돌 버그를 진단하는 함수의 분해를 살펴 보았습니다 .
현대 콘솔 게임에서 대량의 고성능 코드는 어셈블리와 C ++ 사이의 일종의 중간 단계 인 컴파일러 내장 함수를 사용하여 작성됩니다 . 이 구조는 C ++ 함수처럼 보이고 구문 분석 되지만 실제로 단일 기계 명령어로 변환됩니다 . 예를 들어, "벡터 V의 각 값을> = a 및 <= b로 고정"함수는 다음과 같습니다.
// for each v.x, ensure v.x >= a.x && v.x <= b.x
inline __m128 ClampSIMD( const __m128 &v, const __m128 & a, const __m128 & b )
{
return _mm_max_ps( a, _mm_min_ps( v, b ) );
}
이와 같은 기능에서 나는 여전히 특정 기계 명령어 와 관련하여 생각하고 있지만 C로 작성하는 것이 편리하므로 레지스터 색상 및 일정과로드 op 및 기타 지루한 세부 사항에 대해 걱정할 필요가 없습니다.
특히 현명한 컴파일러는 똑똑한 사람이 일을 얼마나 잘 수행 할 수 있는지에 비해 코드를 벡터화하는 데 끔찍하기 때문에 CPU가 지원하는 명령에 대해 알고 있어야합니다. 또한 코드를 정렬하는 방법에 대한 미묘한 세부 사항으로 인해 기계가 수행하는 작업을 이해하지 못하면 성능에 큰 영향을 줄 수 있습니다 .
어셈블리에서는 코드를 작성하지 않아도 어셈블리에서는 여전히 디버깅 을 많이합니다. 컴파일러 최적화는 디버거가 따라 잡을 수없는 방식으로 코드를 적극적으로 재구성하므로 "릴리스 모드"를 디버깅 할 때 가장 좋은 방법은 디스어셈블러를 열고 코드를 추적하는 것입니다. 충돌의 "법의학 디버깅 (Forensic Debugging)"에 관한이 GDC 이야기 는 그 수준에서 디버깅하는 이유와 방법을 설명합니다.
수동 롤 어셈블리가 필요한 문제는 점점 줄어들고 있습니다. "빠른"속도는 가독성과 디버깅 능력이 떨어지게됩니다. 대부분의 경우 속도 문제가 어셈블리로는 더 이상 나을 수없는 것이 아니기 때문에 코드 섹션에서 가장 마지막 최적화 단계 중 하나로 만 수행해야합니다. 요즘 CPU는 훨씬 빨라졌지만 메모리 속도는 그렇지 않았습니다. 종종 다른 것보다 CPU를 통해 데이터가 흐르는 방식을 제어하는 것이 더 중요합니다.
최신 컴파일러를 사용하면 터치 한 레지스터를 처리해야하기 때문에 어셈블리 코드를 최적화하기가 어려워 일반적으로 수작업으로 작성된 코드에서 명령을 다시 정렬 할 수 없습니다. 어셈블리의 필요성을 줄이기 위해 이제 저수준 개념에 액세스하는 데 도움이되는 내장 함수 가 있지만 컴파일러에 친숙하고 반대하지 않고 작업 할 수 있습니다.
PS3의 SPU는 사람들이 여전히 프로세서를 최대한 활용하기 위해 어셈블리를 사용해야하는 영역 중 하나입니다 (예 : 여기 설명 된대로 수동 명령 파이프 라이닝) .