c++ - 행렬 분배 법칙




int로 int에 비해 float 행렬 곱셈으로 float을 수행하는 것이 더 빠른 이유는 무엇입니까? (2)

모든 벡터 벡터 및 행렬 벡터 연산은 내부적으로 BLAS 사용합니다. 서로 다른 아치, CPU, 명령어 및 캐시 크기에 대해 수십 년 동안 최적화 된 BLAS는 정수 유형이 없습니다!

여기에 OpenBLAS의 일부 분과 (그리고 그것을 연결하는 Google 그룹에서 몇 가지 작은 토론 )입니다.

그리고 인텔의 MKL (인텔의 BLAS 구현) 이 정수형에서도 작동하고 있다고 들었 습니다 . 이 이야기 는 흥미 롭습니다 (포럼에서 언급). 비록 임베디드 딥 - 러닝 (Implement Deep-Learning)에서 유용한 작은 정수 타입에 가까워 질수록 짧아 질 것입니다.

1000 개의 행과 10K 열 이상의 두 개의 int 행렬 A와 B가있는 경우, 속도를 높이기 위해 float 행렬로 변환해야하는 경우가 많습니다 (4x 이상).

이 사건이 왜 그런지 궁금합니다. 나는 AVX와 같은 많은 최적화 및 벡터화가 플로트 행렬 곱셈을 사용하여 진행된다는 것을 알고 있습니다. 그러나 정수형 (AVX2)에 대한 지침이 있습니다 (실수하지 않은 경우). 그리고 SSE 및 AVX를 정수로 사용할 수 있습니까?

왜 Numpy 나 Eigen과 같은 행렬 대수 라이브러리 밑에는 경험치가 없으므로 이것을 포착하고 float처럼 정수 행렬 곱셈을 빠르게 수행 할 수 있습니까?

대답에 대해 : @ sascha의 대답은 매우 유익하고 관련성이 있지만, @ chatz의 대답은 int 곱셈에 의한 int가 BLAS 정수 행렬 연산의 존재 여부와 관계없이 느린 실제 이유입니다.


본질적으로 제품을 계산하는이 두 가지 간단한 함수를 컴파일하면 (Eigen 라이브러리를 사용하여)

#include <Eigen/Core>

int mult_int(const Eigen::MatrixXi& A, Eigen::MatrixXi& B)
{
    Eigen::MatrixXi C= A*B;
    return C(0,0);
}

int mult_float(const Eigen::MatrixXf& A, Eigen::MatrixXf& B)
{
    Eigen::MatrixXf C= A*B;
    return C(0,0);
}

-mavx2 -S -O3 플래그를 사용하면 정수 및 부동 소수점 버전과 매우 유사한 어셈블러 코드를 볼 수 있습니다. 가장 큰 차이점은 vpmulldvpmulld 이 2-3 배이며 처리량이 1/2 또는 1/4 인 vmulps 입니다. (최신 인텔 아키텍처에서)

참고 자료 : 인텔 내장 가이드 , "처리량"은 상호 처리량, 즉 지연이 발생하지 않는 경우 (다소 단순화 된 경우) 연산 당 얼마나 많은 클럭 사이클이 사용되는지를 의미합니다.







eigen