어셈블리에서 프로그래밍하는 이유는 무엇입니까? [닫은]


86

모든 하드 코어 저수준 해커들에게 질문이 있습니다. 블로그에서이 문장을 보았습니다. 나는 그것이 일반적인 진술처럼 보이기 때문에 출처가 중요하다고 생각하지 않습니다 (정말 관심이 있다면 Haack입니다).

예를 들어, 많은 최신 3D 게임에는 C ++ 및 어셈블리로 작성된 고성능 코어 엔진이 있습니다.

어셈블리가 진행되는 한-컴파일러가 추가 명령을 내보내거나 과도한 바이트를 사용하는 것을 원하지 않거나 C로 표현할 수없는 (또는없이 표현할 수없는) 더 나은 알고리즘을 사용하고 있기 때문에 컴파일러가 그들을 괴롭히는 것)?

저수준의 것들을 이해하는 것이 중요하다는 것을 완전히 이해합니다. 나는 당신이 그것을 이해 한 후에 어셈블리의 프로그램 을 이해하고 싶습니다 .


1
비슷한 질문 ... 난 생각이 이미
메흐 다드 Afshari

8
Eeeeehh .. 기술적으로 이것은 다른 질문입니다. 그 질문은 둘 다 어셈블리를 배우는 이유이고, 이것이 프로그램에서 프로그램을 배우는 이유입니다. 어떤 .. 다른 것 같아요 ....?
cgp

4
어셈블리에서 프로그래밍하는 이유는 무엇입니까? - 그 질문에 대한 몇 가지 안되고 답변에서 살펴 보자 : 1), 2) 유연하고, 3) 휴대 성을 찾다하기, 4) 테스트 용이성, 5) 가독성, ... 내 코드를 유지 보수를 만들려면)
ivan_ivanovich_ivanoff

9
직업 보안 ........
San Jacinto

3
재미 때문에 .. :)
RainingComputers

답변:


169

이 진술을 잘못 읽은 것 같습니다.

예를 들어, 많은 최신 3D 게임에는 C ++ 및 어셈블리로 작성된 고성능 코어 엔진이 있습니다.

게임 (그리고 요즘 대부분의 프로그램)은 "C ++로 작성"하는 것과 같은 방식으로 "어셈블리로 작성"되지 않습니다. 이 블로그는 게임의 상당 부분이 어셈블리로 설계되었거나 프로그래머 팀이 기본 언어로 어셈블리를 개발하고 있다고 말하는 것이 아닙니다.

이것이 실제로 의미하는 바는 개발자가 먼저 게임을 작성하고 C ++에서 작동하게한다는 것입니다. 그런 다음 프로필을 작성하고 병목 현상이 무엇인지 파악하고 가치가있는 경우 어셈블리에서 문제를 최적화합니다. 또는 이미 경험이 있다면 어떤 부분이 병목이 될지 알고 있으며, 자신이 만든 다른 게임에서 최적화 된 부분을 가지고 있습니다.

어셈블리 프로그래밍 의 요점 은 항상 그랬던 것처럼 속도 입니다. 어셈블러에서 많은 코드 를 작성하는 것은 우스꽝 스러울 것입니다 . 그러나 컴파일러가 인식하지 못하는 최적화가 있으며, 코드 창이 작 으면 사람이 더 잘할 수 있습니다.

예를 들어 부동 소수점의 경우 컴파일러는 상당히 보수적 인 경향이 있으며 아키텍처의 일부 고급 기능을 인식하지 못할 수 있습니다. 오류를 기꺼이 받아들이고 싶다면 일반적으로 컴파일러보다 더 잘할 수 있으며 많은 시간이 소요되는 경우 어셈블리에 약간의 코드를 작성하는 것이 좋습니다.

다음은 좀 더 관련성이 높은 예입니다.

게임의 예

  • SSE 내장 함수를 사용하여 게임 엔진을 최적화하는 방법에 대한 인텔의 기사 . 최종 코드는 인라인 어셈블러가 아닌 내장 함수를 사용하므로 순수 어셈블리의 양은 매우 적습니다. 그러나 그들은 정확히 무엇을 최적화해야하는지 파악하기 위해 컴파일러의 어셈블러 출력을 살펴 봅니다.

  • Quake의 빠른 역 제곱근 . 다시 말하지만, 루틴에는 어셈블러가 없지만 이런 종류의 최적화를 수행하려면 아키텍처에 대해 알아야합니다. 저자는 어떤 연산이 빠르고 (곱하기, 시프트) 느린 지 (나누기, sqrt) 알고 있습니다. 그래서 그들은 느린 작업을 완전히 피하는 제곱근의 매우 까다로운 구현을 내놓았습니다.

고성능 컴퓨팅

  • 게임 영역 밖에서, 과학 컴퓨팅 분야의 사람들은 최신 하드웨어에서 빠르게 실행되도록하기 위해 자주 물건을 최적화합니다. 물리학을 속일 수없는 게임이라고 생각하세요.

    이에 대한 최근의 좋은 예는 Lattice Quantum Chromodynamics (Lattice QCD) 입니다. 이 백서 에서는 IBM Blue Gene / L 에서 PowerPC 440에 최적화 된 매우 작은 컴퓨팅 커널 하나에 문제가 어떻게 발생하는지 설명합니다 . 각 440에는 두 개의 FPU가 있으며 컴파일러가 악용하기 까다로운 일부 특수 삼항 연산을 지원합니다. 이러한 최적화가 없었다면 Lattice QCD는 훨씬 더 느리게 실행되었을 것입니다. 이는 문제가 값 비싼 시스템에서 수백만 CPU 시간을 요구할 때 비용이 많이 듭니다.

    이것이 왜 중요한지 궁금하다면 이 작업에서 나온 Science기사를 확인하십시오 . Lattice QCD를 사용하여이 사람들은 첫 번째 원리에서 양성자의 질량을 계산했고, 작년에 질량의 90 %는 강한 힘 결합 에너지에서 비롯되고 나머지는 쿼크에서 비롯된다는 것을 보여주었습니다. 그건 E = MC 2 행동한다. 요약은 다음과 같습니다 .

위의 모든 경우, 응용 프로그램은되어 있지 설계 또는 어셈블리에 100 %를 기록 - 근처에도 없습니다. 그러나 사람들이 정말 속도가 필요할 때 특정 하드웨어에서 날아 가기 위해 코드의 핵심 부분을 작성하는 데 집중합니다.


12
놀라운 반응. 우리가 이것을 위키에 넣을 수 있기를 바랍니다!
bdd

6
@Paperino ... 할 수 있습니다. StackOverflow에 대한 질문과 답변은 라이선스가 부여 된 크리에이티브 커먼즈 어트 리뷰 션입니다.
Aaron Maenpaa

더 나은 C / C ++를 작성하는 데 도움이되는 asm을 이해하는 방법에 대한 자세한 내용 은 Collatz 추측을 테스트하기 위해이 C ++ 코드가 손으로 작성한 어셈블리보다 빠른 이유를 참조하십시오 . . 내 대답은 컴파일러가 유용한 최적화를 인식하지 못할 때 컴파일러 asm 출력을 읽고 소스를 조정하면 도움이 될 수 있음을 지적합니다. 당신 그래서 정신적으로 (또는 실제로) ASM에서 쓰기, 당신이 원하는 일을하도록 컴파일러에 손 홀드,하지만 지금은 미래 지향적 휴대용 C.이
피터 코르

42

수년 동안 어셈블리 언어로 코딩하지 않았지만 자주 본 몇 가지 이유를 제시 할 수 있습니다.

  • 모든 컴파일러가 특정 CPU 최적화 및 명령어 세트를 사용할 수있는 것은 아닙니다 (예 : 인텔이 가끔씩 추가하는 새로운 명령어 세트). 컴파일러 작성자가 따라 잡을 때까지 기다리면 경쟁 우위를 잃게됩니다.

  • 실제 코드를 알려진 CPU 아키텍처 및 최적화에 더 쉽게 일치시킬 수 있습니다. 예를 들어, 가져 오기 메커니즘, 캐싱 등에 대해 알고있는 것입니다. 이것은 개발자에게 투명해야하지만 사실 그렇지 않다는 것입니다. 이것이 컴파일러 작성자가 최적화 할 수있는 이유입니다.

  • 특정 하드웨어 수준 액세스는 어셈블리 언어를 통해서만 가능 / 실용적입니다 (예 : 장치 드라이버 작성시).

  • 코드의 최종 또는 거의 최종 레이아웃이 무엇인지 이미 알고 있기 때문에 형식적 추론이 고수준 언어보다 어셈블리 언어에서 실제로 더 쉽습니다.

  • API가없는 상태에서 특정 3D 그래픽 카드 (1990 년대 후반)를 프로그래밍하는 것은 어셈블리 언어에서 더 실용적이고 효율적이며 때로는 다른 언어에서는 불가능했습니다. 그러나 여기에는 특정 순서로 데이터를 수동으로 안팎으로 이동하는 것과 같은 액셀러레이터 아키텍처를 기반으로하는 전문가 수준의 게임이 포함되었습니다.

나는 많은 사람들이 더 높은 수준의 언어, 특히 그 언어가 C 일 때 어셈블리 언어를 사용하는 것을 의심합니다. 다량의 범용 코드를 수동으로 최적화하는 것은 비현실적입니다.


19

다른 사람들이 언급하지 않은 어셈블러 프로그래밍의 한 측면이 있습니다. 응용 프로그램의 모든 단일 바이트가 컴파일러가 아니라 자신의 노력의 결과라는 사실을 알게되는 만족감입니다. 80 년대 초반에했던 것처럼 어셈블러에서 전체 앱을 작성하는 것으로 돌아가고 싶지는 않지만 가끔 그 느낌이 그립습니다.


3
어셈블러 작업의 결과! 일반적으로 asm에 많은 매크로를 작성합니다.
Mehrdad Afshari

5
만족뿐만 아니라 정확성에 대한 감사. 그것에 관한 모든 것이 선언 된 간결한 과정은 보는 기쁨입니다.
deau

18

일반적으로 평신도의 어셈블리는 C보다 느리지 만 (C의 최적화로 인해) 많은 게임 (명확히 Doom )은 Assembly에 게임의 특정 섹션을 가져야 일반 컴퓨터에서 원활하게 실행됩니다.

여기에 제가 언급하는 예가 있습니다.


2
+1 매우 사실입니다. 인간은 long asm 코드를 작성하는 데 매우 능숙합니다.
죽은 계정

어셈블러가 작성되었을 때 언급 된 도구를 항상 사용할 수있는 것은 아닙니다.
Marco van de Voort

16

저는 80 대 첫 직장에서 어셈블리 언어로 전문 프로그래밍을 시작했습니다. 임베디드 시스템의 경우 RAM 및 EPROM과 같은 메모리 요구량이 낮았습니다. 리소스에 대해 쉬운 타이트한 코드를 작성할 수 있습니다.

80 년대 후반에 저는 C로 전환했습니다. 코드는 작성, 디버그 및 유지 관리가 더 쉬웠습니다. 아주 작은 코드 스 니펫이 어셈블러로 작성되었습니다. 저에게는 롤-자유 RTOS에서 컨텍스트 전환을 작성할 때였습니다. ( "과학 프로젝트"가 아니면 더 이상하지 말아야 할 일.)

일부 Linux 커널 코드에서 어셈블러 스 니펫을 볼 수 있습니다. 가장 최근에는 spinlock 및 기타 동기화 코드에서 검색했습니다. 이러한 코드 조각은 원자 테스트 및 설정 작업, 캐시 조작 등에 대한 액세스 권한을 얻어야합니다.

나는 당신이 대부분의 일반적인 프로그래밍을 위해 최신 C 컴파일러를 최적화하기가 어려울 것이라고 생각합니다.

나는 당신의 시간이 문제에 대해 더 열심히 생각하고 일을 더 잘하는 데 시간을 보내는 것이 더 낫다는 @altCognito에 동의합니다. 어떤 이유로 프로그래머는 종종 마이크로 효율성에 초점을 맞추고 매크로 효율성을 무시합니다. 성능 향상을위한 어셈블리 언어는 마이크로 효율성입니다. 시스템을 더 넓게보기 위해 뒤로 물러 서면 시스템의 매크로 문제가 노출 될 수 있습니다. 매크로 문제를 해결하면 종종 더 나은 성능 향상을 얻을 수 있습니다. 매크로 문제가 해결되면 마이크로 수준으로 축소됩니다.

마이크로 문제는 한 명의 프로그래머가 통제 할 수 있고 더 작은 영역에 있다고 생각합니다. 거시적 수준에서 행동을 변경하려면 더 많은 사람들과의 의사 소통이 필요합니다. 일부 프로그래머는이를 피합니다. 전체 카우보이 대 팀 일.


10

"예". 그러나 어셈블러에서 코드를 작성할 때 얻을 수있는 이점은 그만한 가치가 없다는 것을 이해하십시오. 어셈블리로 작성하여받은 수익은 단순히 문제에 대해 더 열심히 생각하고 더 나은 방법을 생각하는 데 시간을 보내는 것보다 적은 경향이 있습니다.

Quake와 ID 게임 엔진에 들어가는 모든 고성능 코드 작성을 주로 담당했던 John Carmack과 Michael Abrash는이 에서 자세히 설명 합니다.

나는 또한 오늘날 컴파일러가 매우 똑똑하고 숨겨진 아키텍처 향상을 활용하는 많은 기술을 사용한다는 Ólafur Waage에 동의합니다.


9

요즘에는 적어도 순차 코드의 경우 괜찮은 컴파일러가 거의 항상 숙련 된 어셈블리 언어 프로그래머를 능가합니다. 그러나 벡터 코드의 경우 다른 이야기입니다. 예를 들어 널리 배포 된 컴파일러는 x86 SSE 유닛의 벡터 병렬 기능을 악용하지 않습니다. 저는 컴파일러 작성자이며 SSE를 이용하는 것이 컴파일러를 신뢰하는 대신 스스로 진행해야하는 이유 중 가장 중요한 이유입니다.


이 경우 컴파일러 내장 함수를 사용합니다.
Mehrdad Afshari

여전히 동일하지 않습니다. 레지스터 옵티마이
저가

그것은 당신의 asm 프로그래머가 어떤 종류의 조미료를 가지고 있는지에 달려 있습니다. agner.org/optimize 를 읽고 조정하고있는 마이크로 아키텍처에 대해 배우기 위해 grokked 했다면 , 짧은 시퀀스에 대해서만 컴파일러 이기는 것이 쉬운 경우 가 많습니다 . 작은 함수에 대한 컴파일러 출력을 볼 때 최소한 절반의 시간 동안 사소한 최적화를 놓쳤습니다. 컴파일러가 좋은 곳은 인라인 및 지속적인 전파를 통해 대규모 코드베이스를 최적화하는 것입니다.
Peter Cordes 2017

8

SSE 코드는 적어도 MSVC에서 컴파일러 내장 함수보다 어셈블리에서 더 잘 작동합니다. (즉, 데이터의 추가 사본을 생성하지 않음)


좋은 점은 내장 함수로 괜찮은 작업을 수행하는 컴파일러가 필요하다는 것입니다. Intel과 Gnu 컴파일러는 꽤 훌륭합니다. PGI와 PathScale의 최신 버전이 아직 경쟁력이 있는지 모르겠습니다. 예전에는 그렇지 않았습니다.
Jed

6

직장 내 소스에는 3 ~ 4 개의 어셈블러 루틴 (약 20MB 소스)이 있습니다. 그것들은 모두 SSE (2) 이며 (상당히 큰-2400x2048 이상이라고 생각하십시오) 이미지에 대한 작업과 관련이 있습니다.

취미로 나는 컴파일러에서 일하고 거기에 더 많은 어셈블러가 있습니다. 런타임 라이브러리는 종종 그것들로 가득 차 있으며, 대부분은 (예외를위한 도우미와 같은) 정상적인 절차 체계를 위반하는 것들과 관련이 있습니다.

마이크로 컨트롤러 용 어셈블러가 없습니다. 대부분의 최신 마이크로 컨트롤러에는 주변 하드웨어 (인터럽트 제어 카운터, 전체 구적 엔코더 및 직렬 빌딩 블록) 가 너무 많아서 어셈블러를 사용하여 루프를 최적화 할 필요가 더 이상 필요하지 않은 경우가 많습니다. 현재 플래시 가격에서는 코드 메모리도 마찬가지입니다. 또한 종종 다양한 핀 호환 장치가 있으므로 체계적으로 CPU 전원 또는 플래시 공간이 부족한 경우 업 스케일링은 문제가되지 않습니다.

실제로 100,000 개의 장치를 배송하지 않는 한 프로그래밍 어셈블러를 사용하면 범주를 더 작은 플래시 칩에 맞추는 것만으로도 상당한 비용을 절감 할 수 있습니다. 하지만 나는 그 범주에 속하지 않습니다.

많은 사람들이 임베디드가 어셈블러의 변명이라고 생각하지만 컨트롤러는 Unix 가 개발 된 시스템보다 CPU 성능이 더 높습니다 . (마이크로 칩 은 미화 10 달러 미만 으로 40 및 60 MIPS 마이크로 컨트롤러 와 함께 제공됩니다 .)

그러나 마이크로 칩 아키텍처를 변경하는 것은 쉽지 않기 때문에 많은 사람들이 레거시를 고수하고 있습니다. 또한 HLL 코드는 아키텍처에 매우 의존적입니다 (하드웨어 주변 장치, I / O 제어를위한 레지스터 등을 사용하기 때문). 그래서 때때로 어셈블러에서 프로젝트를 계속 유지해야하는 좋은 이유가 있습니다. 그러나 종종 사람들은 어셈블러가 정말로 필요하다고 스스로 놀립니다.

GOTO를 사용할 수 있는지 물었을 때 교수님의 답변이 마음에 듭니다 (하지만 ASSEMBLER로도 읽을 수 있음) : "이 기능이 필요한 이유에 대해 3 페이지짜리 에세이를 작성할 가치가 있다고 생각하면 사용할 수 있습니다. . 결과와 함께 에세이를 제출하십시오. "

저수준 기능에 대한 지침 원칙으로 사용했습니다. 그것을 사용하기에는 너무 비 좁지 말고 적절한 동기를 부여하십시오. 정당화로 복잡한 추론을 피하기 위해 인위적인 장벽 한두 개 (에세이와 같은)를 던져라.


1
나는 에세이 테스트를 좋아합니다. 나는 이것을 더 자주 사용해야 할 수도 있습니다;)
ex nihilo

5

일부 명령 / 플래그 / 컨트롤은 단순히 C 수준에 없습니다.

예를 들어 x86에서 오버플로를 확인하는 것은 단순 오버플로 플래그입니다. 이 옵션은 C에서 사용할 수 없습니다.


C에서 비트 연산으로 오버플로 플래그를 계산할 수 있습니다.
swegi 2009

@swegi : 그게 상당히 느릴 것 같습니다.
Brian

얼마나 자주 유용합니까? 그리고 그것이 어셈블러에 빠지는 유일한 이유가 될 수 없습니다.

5

결함은 행별로 실행되는 경향이 있습니다 (문장, 코드 포인트 등). 대부분의 문제에서 어셈블리가 상위 수준 언어보다 훨씬 더 많은 라인을 사용한다는 것은 사실이지만, 때때로 당면한 문제에 가장 적합한 (가장 간결하고 가장 적은 라인) 맵인 경우가 있습니다. 이러한 경우의 대부분은 임베디드 시스템의 드라이버 및 비트 뱅잉과 같은 일반적인 용의자와 관련이 있습니다.


3

또 다른 이유는 사용 가능한 컴파일러가 아키텍처에 충분하지 않고 프로그램에 필요한 코드의 양이 프로그래머가 길을 잃을만큼 길거나 복잡하지 않을 수 있습니다. 임베디드 시스템 용 마이크로 컨트롤러를 프로그래밍 해보십시오. 일반적으로 조립이 훨씬 쉽습니다.


3

언급 된 다른 것 외에도 모든 고등 언어에는 특정 제한이 있습니다. 그렇기 때문에 일부 사람들은 코드를 완전히 제어하기 위해 ASM에서 프로그래밍을 선택합니다.

다른 사람들은 20-60KB 범위의 매우 작은 실행 파일을 즐깁니다. 예를 들어 HiEdit 컨트롤의 작성자가 구현 한 HiEditor , 구문 강조 표시 및 최대 50kb의 탭이있는 Windows 용 강력한 편집 컨트롤을 확인합니다. 내 컬렉션에는 ssheets에서 html 렌더링까지 Excell에서 20 개 이상의 골드 컨트롤이 있습니다.


3

많은 게임 개발자들이이 정보에 놀라실 것 같습니다.

내가 아는 대부분의 게임은 가능한 한 어셈블리를 적게 사용합니다. 어떤 경우에는 전혀없고 최악의 경우 하나 또는 두 개의 루프 또는 함수가 있습니다.

이 인용문은 지나치게 일반화되어 있으며 10 년 전처럼 사실에 가까운 곳은 없습니다.

그러나 단순한 사실이 조립에 찬성하는 진정한 해커의 십자군 운동을 방해해서는 안됩니다. ;)


3

128 바이트의 RAM과 4K의 프로그램 메모리가있는 저가형 8 비트 마이크로 컨트롤러를 프로그래밍하는 경우 어셈블리 사용에 대한 선택권이별로 없습니다. 때로는 더 강력한 마이크로 컨트롤러를 사용할 때 정확한 시간에 특정 조치를 취해야합니다. 어셈블리 언어는 명령을 계산하고 코드에서 사용하는 클럭 사이클을 측정 할 수 있으므로 유용합니다.


2

모든 Y2K 개선 노력에 참여했다면 Assembly를 알고 있다면 많은 돈을 벌 수 있었을 것입니다. 그 안에 작성된 레거시 코드가 여전히 많이 있으며 해당 코드는 때때로 유지 관리가 필요합니다.


2

아주 작은 CPU에 대한 아주 작은 프로젝트를 제외하고는 어셈블리에서 전체 프로젝트를 프로그래밍하지 않을 것입니다. 그러나 일부 내부 루프의 전략적 수동 코딩으로 성능 병목 현상을 완화 할 수 있다는 사실을 발견하는 것이 일반적입니다.

어떤 경우에는 실제로 필요한 것은 일부 언어 구조를 최적화 프로그램이 사용 방법을 알아낼 수없는 명령어로 바꾸는 것입니다. 전형적인 예는 벡터 연산과 곱셈-누적 연산이 옵티마이 저가 발견하기 어렵지만 코드를 쉽게 다룰 수있는 DSP 애플리케이션입니다.

예를 들어 SH4의 특정 모델에는 4x4 행렬과 4 개의 벡터 명령어가 포함되어 있습니다. 나는 보았다 거대한 하드웨어 가정 일치하는 4 × 4로 보정 행렬을 확대의 작은 비용으로, 해당 지침과 3 × 3 행렬에 해당하는 C 작업을 대체하여 색 보정 알고리즘의 성능 향상. 이는 12 줄 이하의 어셈블리를 작성하고 관련 데이터 유형 및 스토리지에 대한 일치 조정을 주변 C 코드의 소수 위치에 전달함으로써 달성되었습니다.


2

언급되지 않은 것 같아서 추가 할 것이라고 생각했습니다. 현대 게임 개발에서 작성되는 어셈블리 중 적어도 일부는 CPU 용이 아니라고 생각합니다. 쉐이더 프로그램 형태의 GPU 용 입니다.

이것은 모든 종류의 이유로 필요할 수 있습니다. 때로는 사용 된 더 높은 수준의 셰이딩 언어가 어떤 크기 제약, 속도 또는 어떤 조합에 맞도록 정확한 연산을 원하는 정확한 수의 명령으로 표현할 수 없기 때문입니다. . 어셈블리 언어 프로그래밍에서 평소와 같이 추측합니다.


2

내가 지금까지 본 거의 모든 중대형 게임 엔진 또는 라이브러리에는 4x4 매트릭스 연결과 같은 매트릭스 작업에 사용할 수있는 손으로 최적화 된 어셈블리 버전이 있습니다. 컴파일러는 큰 행렬로 작업 할 때 필연적으로 일부 영리한 최적화 (레지스터 재사용, 최대한 효율적인 방법으로 루프 풀기, 기계 별 명령어 활용 등)를 놓치는 것 같습니다. 이러한 매트릭스 조작 기능은 거의 항상 프로파일의 "핫스팟"입니다.

또한 FastDelegate와 같은 사용자 지정 디스패치를 ​​위해 수작업으로 코딩 한 어셈블리가 많이 사용되는 것을 보았습니다.

마지막으로, Interrupt Service Routines가 있다면 asm은 세상의 모든 차이를 만들 수 있습니다. 인터럽트 하에서 발생하고 싶지 않은 특정 작업이 있으며, 인터럽트 핸들러가 "빠르게 들어오고 나가기를"원합니다. .. 당신은 그것이 asm에 있다면 당신의 ISR에서 무슨 일이 일어날 지 거의 정확하게 알고 있으며, 피 묻은 것들을 짧게 유지하도록 권장합니다 (어쨌든 좋은 습관입니다).


2

게임은 성능에 굶주리고 그 동안 최적화 프로그램은 꽤 훌륭하지만 "마스터 프로그래머"는 어셈블리에서 올바른 부분을 직접 코딩하여 더 많은 성능을 끌어낼 수 있습니다.

먼저 프로파일 링하지 않고 프로그램 최적화를 시작하지 마십시오. 프로파일 링 후 병목 현상을 식별 할 수 있어야하며 더 나은 알고리즘 등을 찾아도 더 이상 잘라 내지 않으면 어셈블리에서 코드를 직접 작성할 수 있습니다.


2

나는 그의 어셈블리 사용에 대해 한 명의 개발자와 개인적으로 이야기했습니다. 그는 휴대용 MP3 플레이어의 컨트롤을 다루는 펌웨어를 작업하고있었습니다. 어셈블리에서 작업하는 데는 두 가지 목적이 있습니다.

  1. 속도 : 지연을 최소화해야합니다.
  2. 비용 : 코드를 최소화하면 코드를 실행하는 데 필요한 하드웨어가 약간 덜 강력 할 수 있습니다. 수백만 대를 대량 생산할 때 이것은 합산 될 수 있습니다.

2

내가 계속하는 유일한 어셈블러 코딩은 리소스가 부족한 임베디드 하드웨어에 대한 것입니다. Leander가 언급했듯이 어셈블리는 여전히 ISR에 적합합니다. 코드가 빠르고 잘 이해되어야하는 .

저에게 두 번째 이유는 어셈블리 기능에 대한 지식을 유지하는 것입니다. CPU가 내 입찰을 수행하기 위해 취하는 단계를 검토하고 이해할 수 있다는 것은 기분이 좋습니다.


2

어셈블러에서 마지막으로 작성한 것은 컴파일러가 libc가없는 위치 독립적 코드를 생성하도록 설득 할 수 없었던 때였습니다.

다음에도 같은 이유가있을 것입니다.

물론 나는 다른 이유가 있었다 .


2

많은 사람들이 어셈블리 언어를 폄하하는 것을 좋아합니다. 그 이유는 코드로 코딩하는 법을 배운 적이없고 모호하게 만났을 뿐이고 놀라거나 다소 겁을 먹게했기 때문입니다. 진정한 재능을 가진 프로그래머는 C 또는 Assembly를 보완하기 때문에 bash는 것은 무의미하다는 것을 이해할 것입니다. 사실 하나의 장점은 다른 하나의 단점입니다. C의 체계화 된 구문 규칙은 명확성을 향상 시키지만 동시에 구조적 규칙이없는 모든 전원 어셈블리를 포기합니다! C 코드 명령은 프로그래밍 의도의 명확성을 강요 할 수있는 논 블로킹 코드를 생성하도록 만들어졌지만 이는 전력 손실입니다. C에서 컴파일러는 if / elseif / else / end 내부의 점프를 허용하지 않습니다. 또는 서로 겹치는 서로 다른 변수에 대해 두 개의 for / end 루프를 작성할 수 없습니다. 자체 수정 코드를 작성할 수 없습니다 (또는 매끄럽지 않은 쉬운 방법으로 작성할 수 없음). 기존의 프로그래머는 위의 내용에 겁을 먹고 기존 규칙을 따르기 위해 이러한 접근 방식의 힘을 사용하는 방법조차 모를 것입니다. . 여기에 진실이 있습니다 : 오늘날 우리는 우리가 사용하는 응용 프로그램보다 훨씬 더 많은 작업을 수행 할 수있는 컴퓨팅 능력을 갖춘 기계를 가지고 있지만 인간의 두뇌는 규칙없는 코딩 환경 (= 어셈블리)에서 코딩하기에는 너무 무능력하고 제한적인 규칙이 필요합니다. 스펙트럼을 줄이고 코딩을 단순화합니다. 위에서 언급 한 한계 때문에 엄청나게 비효율적이지 않고는 C 코드로 작성할 수없는 코드를 직접 작성했습니다. 그리고 대부분의 사람들이 어셈블리에서 글을 쓰는 주된 이유라고 생각하는 속도에 대해서는 아직 이야기하지 않았습니다. 글쎄요 당신이 C로 생각하는 것에 제한되어 있다면 당신은 영원히 컴파일러의 노예입니다. 나는 항상 체스 플레이어 마스터가 이상적인 어셈블리 프로그래머가 될 것이라고 생각했지만 C 프로그래머는 그냥 "Dames"를 연기했습니다.


1
자체 수정 코드는 JIT-once / run-many 시나리오를 제외한 대부분의 최신 CPU 성능에 유용하지 않습니다. 그러나 즉시 상수로 채우는 것은 재미있는 가능성입니다. C goto는 함수 내에서 구조화되지 않은 점프를 허용합니다. if()동일한 함수에서 또는 루프 내부의 블록에 포함 합니다. 예 : godbolt.org/z/IINHTg . 스위치 / 케이스를 do{}while()루프로 사용하여 풀린 루프로의 점프를 표현하는 Duff의 장치를 참조하십시오 . 그러나 어느 시점에서 당신이 그 수준의 혼란에 빠지면 asm으로 작성하는 것이 더 명확해질 수 있습니다.
Peter Cordes 2019

1
(물론 Duff의 장치는 사후 증가 주소 지정이있는 시스템에서만 유용합니다. 그렇지 않으면 풀린 루프 내부의 진입 점이 최적화 목적의 대부분을 무효화합니다.)
Peter Cordes

1

더 이상 속도가 아니라 Control . 속도는 때때로 제어에서 비롯되지만 어셈블리에서 코딩 하는 유일한 이유 입니다. 다른 모든 이유는 제어로 귀결됩니다 (예 : SSE 및 기타 손 최적화, 장치 드라이버 및 장치 종속 코드 등).


1

GCC 를 능가 할 수있는 경우 와 Visual C ++ 2008 (Visual C ++ 9.0이라고도 함) 사람들은 그것이 어떻게 가능한지 인터뷰하는 데 관심이있을 것입니다.

이것이 바로 지금 어셈블리에서 내용을 읽고 필요할 때 __asm ​​int 3을 작성하는 이유입니다.

도움이 되었기를 바랍니다.


1

몇 년 동안 어셈블리를 작성하지 않았지만 두 가지 이유는 다음과 같습니다.

  • 사물의 도전! 몇 달 전 x86 어셈블리 ( DOS 와 Windows 3.1 시절)로 모든 것을 작성했습니다 . 기본적으로 낮은 수준의 작업, 하드웨어 I / O를 배웠습니다. 등을 .
  • 어떤 경우에는 크기를 작게 유지했습니다 ( TSR 작성시 DOS 및 Windows 3.1에서도 마찬가지 임).

저는 계속해서 코딩 어셈블리를 봅니다. 그것은 그저 도전과 기쁨에 지나지 않습니다. 나는 그렇게 할 다른 이유가 없습니다 :-)


1

나는 이전 프로그래머가 대부분 어셈블리 코드로 작성한 DSP 프로젝트를 인수했습니다. 단, 부동 소수점 (고정 소수점 DSP에서!)을 사용하여 C로 작성된 톤 감지 로직을 제외하고는 예외입니다. 톤 감지 로직은 실시간의 약 1/20에서 실행되었습니다.

나는 거의 모든 것을 처음부터 다시 작성했습니다. 작은 인터럽트 핸들러와 이전 코드보다 100 배 이상 빠르게 실행되는 인터럽트 처리 및 저수준 주파수 감지와 관련된 수십 줄의 코드를 제외하고 거의 모든 것이 C에있었습니다.

명심해야 할 중요한 점은 많은 경우 큰 루틴보다 작은 루틴으로 속도를 향상시킬 수있는 기회가 훨씬 더 많을 것입니다. 특히 손으로 작성한 어셈블러가 모든 것을 레지스터에 맞출 수 있지만 컴파일러는 그렇지 않은 경우 꽤 관리합니다. 루프가 어쨌든 레지스터에 모든 것을 유지할 수 없을만큼 충분히 크면 개선 할 기회가 훨씬 적습니다.


0

Android 휴대폰에서 Java 애플리케이션의 바이트 코드를 해석하는 Dalvik VM은 디스패처에 어셈블러를 사용합니다. 이 영화 (약 31 분 정도 소요되지만 전체 영화를 볼 가치가 있습니다!)

"인간이 컴파일러보다 더 잘할 수있는 경우가 여전히 있습니다."


0

나는 그렇지 않지만 적어도 시도하고, 미래의 어느 시점에서 열심히 노력할 것을 요점으로 만들었습니다 (곧 희망합니다). 저수준에 대해 더 많이 알고 고수준 언어로 프로그래밍 할 때 배후에서 작동하는 방식을 아는 것은 나쁜 일이 아닙니다. 안타깝게도 개발자 / 컨설턴트 및 부모로서의 정규직을 구하기 란 쉽지 않습니다. 그러나 나는 때가되면 줄 것이다. 그것은 확실하다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.