Các thư viện hiệu năng cao MASS
MASS là viết tắt của Hệ thống con tăng tốc toán học (Mathematical Acceleration Subsystem). Nó bao gồm các thư viện về các hàm toán học đặc biệt được điều chỉnh cho hiệu năng tối ưu trên các nền tảng điện toán khác nhau của IBM. Ban đầu MASS đã được IBM khởi chạy vào năm 1995. Và từ đó đã liên tục được cải tiến và mở rộng.
Hiện đang có các phiên bản của MASS cho tất cả các bộ vi xử lý POWER™ của IBM®, đang chạy các hệ thống điều hành AIX® hoặc Linux®. Ngoài ra còn có các phiên bản dành cho các siêu máy tính System BlueGene®/Lvà the IBM System BlueGene®/P của IBM cũng như giải pháp Cell Broadband Engine™ (Cell/B.E.™) của IBM. Các thư viện chứa các triển khai thực hiện có tăng tốc của các hàm cơ sở như các hàm lượng giác và hyperbolic và hàm nghịch đảo, hàm lũy thừa, hàm logarit, hàm mũ, hàm lỗi và các hàm khác của chúng. Danh sách đầy đủ về các hàm bao gồm có sẵn trên trang Hệ thống con tăng tốc toán học của IBM.
Có cả thư viện vô hướng và véc tơ và cũng có các thư viện đa dữ liệu (SIMD) lệnh đơn cho Cell/B.E. và POWER7. Lưu ý rằng việc xử lý chính xác và xử lý ngoại lệ có thể không giống nhau trong các hàm MASS và các hàm thư viện hệ thống. Các thư viện được đóng gói bằng các trình biên dịch XL C/C++ và XL Fortran của IBM và cũng có sẵn trên trang web MASS, cho những người dùng của các trình biên dịch khác (chẳng hạn như gcc) với phần cứng đã định.
Các thư viện có thể gọi được từ các chương trình nguồn C, C++ hoặc Fortran. Các trình biên dịch XL C/C++ và XL Fortran của IBM có khả năng nhận ra những cơ hội sử dụng MASS để tăng tốc chương trình nguồn và gọi nó tự động mà không cần các thay đổi chương trình nguồn. Bài viết này cho bạn thấy làm thế nào để triển khai thực hiện một kỹ thuật có thể giúp tổ chức của bạn tận dụng khả năng mạnh mẽ này.
Các chương trình có thể được lợi gì?
Bất kỳ chương trình C, C++ hoặc Fortran đều có chứa các cuộc gọi đến các hàm thư viện toán học (như hàm mũ, hàm logarit, hàm sin, hàm cos, v.v) trong một vòng lặp có thể được lợi nhiều từ các kỹ thuật được mô tả trong bài viết này.
Véc tơ hóa tự động là một quá trình mà theo đó các trình biên dịch XL C/C++ hay Fortran của IBM nhận ra cơ hội để cải thiện hiệu năng của chương trình đang được biên dịch bằng cách thay thế một cuộc gọi đến một hàm (bên trong của C/C++ libm hoặc Fortran) thư viện chuẩn trong một vòng lặp bằng một cuộc gọi đến hàm véc tơ MASS tương ứng. Do các hàm véc tơ MASS nhanh hơn nhiều (với hệ số tăng đến khoảng 30 lần) so với một cuộc gọi lặp lại tới một hàm thư viện chuẩn, nên việc cải thiện hiệu năng kết quả có thể đáng kể.
Một ví dụ đơn giản là một vòng lặp để tính toán một hàm cụ thể có nhiều đối số, ví dụ như chương trình Fortran sau đây.
subroutine sub (y, x, n)
real*8 y(*), x(*)
integer n, i
intrinsic exp
do i=1,n
y(i) = exp(x(i)) ! standard intrinsic
end do
end subroutine
|
Với các tùy chọn trình biên dịch thích hợp, trình biên dịch sẽ nhận ra cơ hội để tăng tốc chương trình bằng cách thay thế cuộc gọi lặp lại đến hàm exp() bằng một cuộc gọi duy nhất đến hàm véc tơ MASS tương ứng vexp(), kết quả là một chương trình chạy như thể ngay từ đầu nó đã được viết ra như sau:
include 'massv.include'
subroutine sub (y, x, n)
real*8 y(*), x(*)
integer n
call vexp (y, x, n) ! MASS vector function
end subroutine
|
Đây chỉ là một ví dụ đơn giản, thể hiện ý tưởng cơ bản đằng sau việc véc tơ hóa tự động. Các trình biên dịch XL thực sự có thể nhận ra nhiều cơ hội phức tạp hơn và cũng sẽ cố gắng sắp xếp lại các lệnh trong chương trình nguồn khi cần thiết để tạo các cơ hội véc tơ hóa tự động.
Một ví dụ thực tế và phức tạp hơn được xem xét trong phần trường hợp nghiên cứu của bài viết này.
Các tùy chọn trình biên dịch với việc véc tơ hóa tự động
Bạn có thể biên dịch các chương trình với bất kỳ một trong các bộ các tùy chọn sau:
- -qhot -qnostrict (với Fortran)
- -qhot -qnostrict -qignerrno (với C/C++)
- -qhot -O3
- -O4
- -O5
Khi bạn biên dịch một chương trình bằng cách sử dụng một trong các bộ tùy chọn này, trình biên dịch tự động cố thử véc tơ hóa cuộc gọi đến các hàm toán của hệ thống bằng cách gọi các hàm véc tơ MASS tương đương (trừ các cuộc gọi đến các hàm sau, là các hàm ngoại lệ: vdint vatan2, vsatan2, vdnint, , vcosisin, vscosisin, vlog21p vqdrt, vsqdrt, vrqdrt, vsrqdrt, vpopcnt4, vpopcnt8, vexp2, vexp2m1, vsexp2, vsexp2m1, vlog2,, vslog2 và vslog21p). Nếu trình biên dịch không thể véc tơ hóa chương trình như vậy, nó sẽ thực hiện gọi tự động các hàm vô hướng MASS tương đương. Để véc tơ hóa hoặc vô hướng hóa tự động, trình biên dịch sử dụng các phiên bản của các hàm MASS có trong thư viện libxlopt.a của trình biên dịch. Bạn không cần phải thêm bất kỳ cuộc gọi đặc biệt nào nữa đến các hàm MASS trong mã của bạn hoặc liên kết rõ ràng đến thư viện xlopt.
Ngoài bất kỳ các bộ tùy chọn có trước, khi tùy chọn –qipa có hiệu lực, nếu trình biên dịch không thể véc tơ hóa được, nó sẽ cố gắng nội tuyến các hàm vô hướng MASS trước khi quyết định gọi chúng.
Nếu bạn muốn vô hiệu hóa việc véc tơ hóa tự động, bạn có thể thêm tùy chọn -qhot=novector.
Sau đây là một trường hợp nghiên cứu về một ứng dụng thực tế — một phép biến đổi Phu ri ê rời rạc (DFT) — cho thấy các cải tiến hiệu năng nhận được khi biên dịch với các tùy chọn của trình biên dịch khác nhau. Ứng dụng đủ đơn giản để được minh họa rõ ràng, nhưng cũng đủ phức tạp để cung cấp các cơ hội tối ưu hóa không tầm thường.
Việc tính giờ cho cả hai chương trình đã được thực hiện bằng chương trình của trình điều khiển được cho trong Phụ lục 3, trên một máy tính POWER6 chạy ở 4,704 GHz.
Phụ lục 1 cho thấy chương trình nguồn DFT Fortran. Nó chứa một vòng lặp lồng nhau để gọi hàm exp(), cos() và sin(), theo sau là một vòng lặp để gọi hàm sin () và sqrt (). Chương trình được biên dịch theo tùy chọn -O3 (không thực hiện véc tơ hóa tự động) và theo tùy chọn -O4 (thực hiện véc tơ hóa tự động). Kết quả được chỉ ra trong Hình 1.
Lưu ý rằng lợi ích của việc véc tơ hóa tự động tăng lên khi kích cỡ bài toán được tăng lên, đạt tới một hệ số cải thiện tăng gấp 8,94 lần với một kích cỡ bài toán là 2000.
Hình 1: So sánh hiệu năng của DFT Fortran với các tùy chọn biên dịch -O3 và -O4, với các kích cỡ bài toán khác nhau.
Phụ lục 2 cho thấy một phiên bản C của chương trình DFT Fortran trong Phụ lục 1 (Nó chứa một thường trình consume() giả để cho việc phân tích giữa-thủ tục [IPA] của trình biên dịch không thể nhận thấy rằng kết quả tính toán này thực tế không được sử dụng trong ví dụ minh họa này và do đó sẽ tối ưu hóa ngay toàn bộ chương trình).
Chương trình được biên dịch theo tùy chọn -O3 (không thực hiện véc tơ hóa tự động), theo tùy chọn -O4 (thực hiện véc tơ hóa tự động) và -O5 (thực hiện véc tơ hóa tự động cũng như IPA). Kết quả được chỉ ra trong Hình 2.
Như được minh họa trong ví dụ Fortran, lợi ích của việc véc tơ hóa tự động tăng lên khi kích thước bài toán được tăng lên, đạt tới hệ số gấp 6,00 lần với n = 2000. Ngoài ra, việc kích hoạt IPA tại -O5 cung cấp tăng tốc thêm 1,22 lần do nó có thể xác định rằng các đầu vào và các đầu ra không phải là bí danh (có nghĩa là, chúng không chồng lấp lên nhau trong bộ nhớ), cho phép nó véc tơ hóa cuộc gọi đến atan2 trong phép biến đổi sang hệ tọa độ cực. Sự tăng tốc của -O5 hơn -O3 là 7,33 lần với n=2000.
Hình 2: So sánh hiệu năng DFT C với các tùy chọn biên dịch -O3, -O4 và -O5, với các kích cỡ bài toán khác nhau.
Bài viết này đã cung cấp cho bạn một mô tả về các thư viện MASS của IBM và các khả năng véc tơ hóa tự động của các trình biên dịch XL C/C++ và XL Fortran của IBM. Ngoài ra, bài viết đã giải thích cách sử dụng các tùy chọn trình biên dịch khác nhau trên một chương trình ví dụ (phép biến đổi Phu ri ê rời rạc), chỉ cho bạn biết cách có thể đạt được các tăng tốc lên tới 8,94 lần so với các tốc độ trước đây nhờ sử dụng các trình biên dịch thông qua cuộc gọi tự động của MASS bằng véc tơ hóa tự động.
Cuộc trình diễn này là nhằm khuyến khích những người dùng với các chương trình để gọi các hàm toán học để thử nghiệm với các tùy chọn trình biên dịch có sẵn và hưởng lợi từ sự tăng tốc là kết quả của việc véc tơ hóa tự động trình biên dịch XL C/C++ hoặc XL Fortran của IBM .
Phụ lục 1 – Chương trình nguồn Biến đổi Phu ri ê rời rạc (DFT) của Fortran
subroutine dft (x, a, phi , n)
real*8 x(n), a(n), phi(n)
integer n
! Compute discrete Fourier transform of real inputs
! x(i) and convert to polar form.
real*8, parameter :: pi=3.1415926535897932384d0
real*8 y_re(n), y_im(n), t, term_re, term_im
intrinsic exp, cos, sin, sqrt, atan
y_re(1:n) = 0.d0
y_im(1:n) = 0.d0
do k=1,n
! compute y(k), k-th DFT output
do i=1,n
! compute i-th term of y(k):
! x(k)*exp(-2*pi*I*(k-1)*(i-1)/n)
! compute real and imaginary parts of i-th term
! using exp(I*t)=exp(t)*(cos(t)+I*sin(t))
t = -2.d0*pi*(k-1)*(i-1)/n
term_re = x(i) * cos(t) * exp(t)
term_im = x(i) * sin(t) * exp(t)
! add term to sum
y_re(k) = y_re(k) + term_re
y_im(k) = y_im(k) + term_im
end do
end do
! transform y to polar coordinates
do k=1,n
! compute amplitude of y(k)
a(k) = sqrt (y_re(k)**2 + y_im(k)**2)
! compute phase of y(k)
phi(k) = atan (y_im(k) / y_re(k))
end do
end subroutine
! initialize input data
subroutine init (a, n)
real*8 a(n)
integer n
intrinsic sin,sqrt
do j=1,n
a(j)=sin(1.d0/sqrt(real(j,8)))
end do
end subroutine
|
Phụ lục 2 – Chương trình nguồn Biến đổi Phu ri ê rời rạc (DFT) của C
#include <math.h>
#define PI 3.1415926535897932384
void dft(double x[],double a[],double phi[],int *m)
{
double y_re[NMAX], y_im[NMAX], t, s, term_re, term_im;
int i,j,k,n=*m;
for(i=0;i<n;++i) {
y_re[i]=y_im[i]=0;
}
for(k=0;k<n;++k)
{
// compute y(k), k-th DFT output
for(i=0;i<n;++i)
{
// compute i-th term of y(k):
// x(k)*exp(-2*pi*I*(k-1)*(i-1)/n)
// compute real and imaginary parts of i-th term
// using exp(I*t)=exp(t)*(cos(t)+I*sin(t))
t=-2.*PI*k*i/(double)n;
term_re=x[i]*exp(t)*cos(t);
term_im=x[i]*exp(t)*sin(t);
// add term to sum
y_re[k]+=term_re;
y_im[k]+=term_im;
}
}
// transform y to polar coordinates
for(k=0;k<n;++k)
{
// compute amplitude of y(k)
a[k]=sqrt(y_re[k]*y_re[k]+y_im[k]*y_im[k]);
// compute phase of y(k)
phi[k]=atan2(y_im[k],y_re[k]);
}
}
// initialize input data
void init(double a[],int *m)
{
int j,n=*m;
for(j=0;j<n;++j)
{
a[j]=sin(1./sqrt((double)j+1.0));
}
}
// Dummy function to use result, preventing compiler from
// optimizing away the computation.
void consume(double a[],double b[],double c[])
{
}
|
Phụ lục 3 – Chương trình trình điều khiển
Đây là chương trình của trình điều khiển Fortran đã được sử dụng để tính giờ các mã DFT.
program main
interface
subroutine dft(x,a,phi,n)
real*8 x(n),a(n),phi(n)
integer n
end subroutine
subroutine init(a,n)
real*8 a(n)
integer n
end subroutine
subroutine consume(a,b,c)
real*8 a(*),b(*),c(*)
end subroutine
end interface
! Parameters:
! nmax is the problem size.
! nrep is the number of repetitions of the
! problem. This should be chosen so that
! the elapsed time is long enough to give
! sufficient timing resolution.
! cyc is the clock frequency in Hz for the
! processor that the program is to be run on.
! (Can be found from AIX command pmcycles.)
integer, parameter :: nmax=1000
integer, parameter :: nrep=100
real*8, parameter :: cyc=4704000000.d0
real*8 x(nmax), a(nmax), phi(nmax)
real*8 tx, ty, accum, del(4)
intrinsic sin, sqrt
real*8 rtc
del(4)=0.d0
acc = 0.d0
do k=1,nrep
tx=rtc()
call init(x,nmax)
call dft(x,a,phi,nmax)
ty=rtc()
call consume(x,a,phi)
do j=1,nmax
acc = acc + a(j) + phi(j)
end do
del(4) = del(4) + (ty-tx)
end do
del(1) = del(4)/real(nmax,8)
del(2) = del(1)/real(nrep,8)
del(3) = cyc*del(2)
print *,'acc=',acc/real(nrep,8),' n=',nmax,
& ' r=',nrep, ' a=',del(1),' b=',del(2),
& ' c=',del(3),' w=',del(4)
end program
|
Hiệu năng chính xác đạt được có thể khác nhau tùy thuộc vào loại bộ vi xử lý được sử dụng và cấu hình của nó, cũng như vào phiên bản của trình biên dịch được sử dụng. Do đó, bạn có thể trải nghiệm hiệu năng khác với hiệu năng đã đạt được trong các thử nghiệm được mô tả ở đây.
Học tập
- Hệ thống con tăng tốc
tính toán của IBM: Cung cấp các nội dung, cách sử dụng, hiệu năng
và các thông tin chính xác cho các thư viện MASS.
- XL C/C++ của IBM về Hướng dẫn người dùng AIX: Cung cấp thêm chi
tiết về các cờ của trình biên dịch.
- XL C/C++ của IBM về hướng dẫn lập trình và tối ưu hóa AIX: Cung
cấp thêm chi tiết về các thư viện hiệu năng cao.
- XL Fortran của IBM về Hướng dẫn người dùng AIX: Cung cấp thêm chi
tiết về các cờ của trình biên dịch.
- XL Fortran của IBM về Hướng dẫn lập trình và tối ưu hóa AIX: Cung
cấp thêm chi tiết về các thư viện hiệu năng cao.
- Hướng
dẫn điều chỉnh và giới thiệu về bộ xử lý POWER4: Sách Đỏ này có
nhiều chi tiết về các cờ tối ưu hóa của trình biên dịch.
- AIX và UNIX: Truy
cập vào vùng UNIX và AIX của developerWorks để mở rộng các kỹ năng UNIX
của bạn.
- Mới đến AIX và
UNIX: Truy cập vào trang web Mới đến với AIX và UNIX để tìm hiểu
về AIX và UNIX.
- Các sự
kiện kỹ thuật và webcast của developerWorks: Theo sát với các sự
kiện kỹ thuật và webcast của developerWorks.
- AIX 5L Wiki: Một môi trường cộng tác với các thông tin kỹ thuật
liên quan đến AIX.
- Podcasts: Bắt
đầu và theo sát với các chuyên gia kỹ thuật của IBM.
Lấy sản phẩm và công nghệ
- Phần mềm dùng thử
của IBM: Xây dựng dự án phát triển tiếp theo của bạn với phần mềm
để tải về trực tiếp từ developerWorks.
Thảo luận
- Tham gia vào các diễn đàn AIX và UNIX:
- AIX 5L — tài liệu kỹ thuật
- AIX cho Diễn đàn của các nhà phát triển
- Quản lý các hệ thống Cụm
- Trợ lý Hỗ trợ của IBM
- Các công cụ hiệu năng — tài liệu kỹ thuật
- Ảo hóa — tài liệu kỹ thuật
- Nhiều hơn nữa về các diễn đàn UNIX và AIX
- Tham gia vào các blog
developerWorks và dành tâm trí cho cộng đồng
developerWorks.
- Tham gia vào C/C++
Café, trong đó bao gồm các tính toán khoa học với blog C/C++
Robert Enenkel làm việc trong nhóm Các trình biên dịch tối ưu (Optimizing Compiler Group) tại Phòng thí nghiệm Toronto của IBM; trước đây ông là nghiên cứu viên tại Trung tâm Nghiên cứu cao cấp của IBM (CAS). Enenkel nhận được bằng Cử nhân khoa học, Thạc sĩ khoa học và bằng tiến sĩ triết học của Đại học Toronto, với luận án về lĩnh vực các phương pháp số song song cho các phương trình vi phân. Ông hiện đang nghiên cứu và phát triển về điện toán số vì nó liên quan đến các trình biên dịch và các hệ điều hành, bao gồm cả số học dấu phẩy động, các thư viện hàm toán học và điều chỉnh hiệu năng của các thuật toán. Tiến sĩ Enenkel đã nhận được nhiều giải thưởng về sáng chế của IBM và giải thưởng công nhận tác giả. Có thể tìm thêm nhiều thông tin tại trang web của ông tại https://www-927.ibm.com/ibm/cas/toronto/people/members/renekel.shtml.
Daniel Zabawa làm việc trong nhóm Các trình biên dịch tối ưu (Optimizing Compiler Group) tại Phòng thí nghiệm Toronto của IBM. Ông đã nhận bằng Cử nhân khoa học và Thạc sĩ khoa học về Khoa học Máy tính của Đại học Toronto. Zabawa hiện đang thực hiện nghiên cứu và phát triển về tối ưu hóa và lập biểu vòng lặp, các thuật toán dấu phẩy động cho các kiến trúc chỉ số trên và thực hiện điều chỉnh các hàm toán học dấu phẩy động.