이것은 명백한 들릴지 모르지만, 컴퓨터가 실행되지 않는 공식을 , 그들이 실행 코드를 , 얼마나 오랫동안 실행이 소요 그들이 어떤 개념이 코드 구현에 간접적으로 만 실행하고 코드에 직접 의존한다. 논리적으로 동일한 두 코드 조각은 매우 다른 성능 특성을 가질 수 있습니다. 특히 행렬 곱셈에서 발생할 수있는 몇 가지 이유는 다음과 같습니다.
- 여러 스레드를 사용합니다. 여러 개의 코어가없는 최신 CPU는 거의 없으며, 최대 8 개까지 보유하고 있으며, 고성능 컴퓨팅을위한 특수 머신은 여러 소켓에서 64 개를 쉽게 가질 수 있습니다. 일반적인 프로그래밍 언어에서 명백한 방식으로 코드를 작성하면 그 중 하나만 사용합니다 . 다시 말해, 실행중인 컴퓨터의 사용 가능한 컴퓨팅 리소스 중 2 % 미만을 사용할 수 있습니다.
- SIMD 명령어 사용 (혼란스럽게도 "벡터화"라고하지만 질문의 텍스트 인용 부호와는 다른 의미로 사용됩니다). 본질적으로 4 또는 8 정도의 스칼라 산술 명령어 대신 CPU 에 4 또는 8 정도의 레지스터에서 병렬로 산술을 수행하는 하나의 명령어를 제공하십시오 . 이것은 문자 그대로 약간의 계산을 할 수 있습니다 (완전히 독립적이며 명령 세트에 적합 할 때) 4 또는 8 배 빠릅니다.
- 더 똑똑한 캐시 사용 . 메모리 액세스는 시간적으로 공간적으로 일관성 이있는 경우 더 빠릅니다 . 즉, 연속적인 액세스는 근처의 주소에 대한 것이고, 주소에 두 번 액세스 할 때는 오래 멈추지 않고 빠르게 두 번 연속해서 액세스합니다.
- GPU와 같은 가속기를 사용합니다. 이 장치는 CPU와는 매우 다른 야수이며 효율적으로 프로그래밍하는 것은 그 자체의 예술적 형태입니다. 예를 들어 수십 개의 코어가 수십 개의 코어 그룹으로 그룹화되어 있으며이 그룹은 리소스를 공유합니다. 일반 메모리보다 훨씬 빠른 몇 KiB의 메모리를 공유하며 그룹의 코어가
if
그 그룹의 다른 모든 사람들이 그것을 기다려야한다고 진술하십시오.
- 엄청난 수의 새로운 두통을 유발하지만 물론 훨씬 더 큰 컴퓨팅 리소스에 액세스 할 수있는 여러 컴퓨터 (수퍼 컴퓨터에서 매우 중요)에 작업 을 분산시킵니다 .
- 똑똑한 알고리즘. 행렬 곱셈의 경우 위의 트릭으로 적절하게 최적화 된 간단한 O (n ^ 3) 알고리즘은 종종 적절한 행렬 크기를 위해 하위 입방체 보다 빠르지 만 때로는 이기게됩니다. 희소 행렬과 같은 특수한 경우 특수 알고리즘을 작성할 수 있습니다.
많은 똑똑한 사람들이 위의 트릭을 사용하고 일반적으로 어리석은 플랫폼 별 트릭을 사용하여 일반적인 선형 대수 연산을 위해 매우 효율적인 코드를 작성했습니다 . 따라서 수식을 행렬 곱셈으로 변환 한 다음 성숙한 선형 대수 라이브러리를 호출하여 계산을 구현하면 해당 최적화 노력의 이점이 있습니다. 반대로, 고급 언어로 공식을 명백하게 작성하면 결국 생성되는 머신 코드는 이러한 트릭을 모두 사용하지 않으며 그리 빠르지 않습니다. 이것은 매트릭스 공식을 취하고 자신이 작성한 순진한 행렬 곱셈 루틴을 호출하여 구현하는 경우에도 마찬가지입니다 (명확한 방식으로).
만들기 코드는 빠른 작업 소요 성능의 마지막 온스를 원하는 경우 작업을 꽤 많이, 자주. 많은 중요한 계산이 두 개의 선형 대수 연산의 조합으로 표현 될 수 있기 때문에 이러한 연산에 대해 고도로 최적화 된 코드를 작성하는 것이 경제적입니다. 하지만 일회용 일회성 유스 케이스? 아무도 당신을 제외하고는 신경 쓰지 않으므로 그것을 최적화하는 것은 경제적이지 않습니다.