UEFI 스터디 13차 - 뜌땨이우뜌땨야

1 minute read

Published:

최적화의 범인을 찾아라

이전 스터디에서 테스트 관련 문제가 있었다.
나의 코드 -> TEMP = X * Y => result = TEMP * 4 만잡아야한다.
근데 이전에 용진이형의 테스트에서 뜬금 없이 TEMP = X * Y => result = TEMP + TEMP + TEMP + TEMP;
을 잡아 버렸다. 범인은 빌드도구와 기드라 중 누구이며 어떻게 개선해야할까?

어셈블리 = 기계어 1대1번역이란 것에서 힌트를 얻었다.
기드라 좌측에 리스팅에선 low pcode보다 앞서 어셈블리를 보여주는데, 이는 기계어의 1대1이므로, 만약 다른 C코드로 작성된 드라이버가
동일한 어셈블리 코드를 가지고 있다면, 이는 빌드도구의 잘못이다.
반면 다른 어셈블리 코드를 가지고 있으나 우측 디컴파일된 C언어나 p코드쪽에서 변화가 있다면 이는 기드라의 잘못이다.

테스트할 리스트들

(test_0)

(test_0_1)

(test_0_2)

각각 곱하기, 쉬프트 연산 사용, 덧셈 네번이다.(쉬프트 연산은 실수로 2가아닌 4로 했지만 넘어가도록 하자.)
여기에선 모두 다르지만 리스팅을 볼 경우..

결과


모두 SHL 어셈블리로 번역된 것을 볼 수 있다.
즉 범인은 빌드 도구가 맞았다.

그러나


나는 당연하게도 어셈블리가 SHL 연산(좌측 쉬프트) 이기에 하이 피코드로도 INT_LEFT로 번역 될 줄 알았는데
INT_MULT로 번역이 되었다.
이로서 빌드전 C코드에서의 배치만으로 테스트 데이터를 만드는 것은 어렵지 않나라고 생각을 했다.

우리의 스크립트는 high p-code를 대상으로 하기때문에 정말 우리가 의도한대로 모든 하이 pcode에서의 경우를 고려하기 위해선
(1) 디스어셈블 결과가 의도한 opcode 여야함 (2)어떤 방?법을 통해서 우리가 highpcode변환시의 pcode opcode와 그 순서가 동일해야함

또 나의 실수도 하나 확인했다. 나는 당연하게 곱하기는 -> IMUL opcode -> INT_MULT pcode opcode로 변환될 줄 알고
범위 명세를 C코드 생각으로 작성했다.(곱하기, 나누기 쉬프트 이런식으로 말이다.) 근데 이제는 Pcode op로 써야하지 않나 싶다.

추가로 이런 생각도 들었다.

  • 우리는 빌드도구가 멋대로 ‘최적화’를 했다고 생각했으나 과연 덧셈은 어셈블리 add로, 곱셈은 mul로, 쉬프트는 SHL로 변환될것이라 확신하는 것이 과연 맞는가? C언어 연산과 해당 어셈블리 연산은 1대1 매칭 관계가 아니니까.
  • 검증 및 코드 생성에서 high pcode에서의 형태를 고려하여 데이터를 생성해야할 필요가 생기지 않았나싶다.