tôi thử nghiệm các chức năng đơn giản sau đâyAVX hoạt động vô hướng là nhanh hơn nhiều
void mul(double *a, double *b) {
for (int i = 0; i<N; i++) a[i] *= b[i];
}
với mảng rất lớn để nó là băng thông bộ nhớ bị ràng buộc. Mã thử nghiệm tôi sử dụng ở bên dưới. Khi tôi biên dịch với -O2
mất 1.7 giây. Khi tôi biên dịch với -O2 -mavx
chỉ mất 1.0 giây. Các hoạt động vô hướng mã hóa không được mã hóa vex chậm hơn 70%! Tại sao điều này?
Đây là phiên bản dành cho -O2
và -O2 -mavx
.
hệ thống: [email protected] (Skylake) 32 GB mem, Ubuntu 16.10, GCC 6.3
mã kiểm tra
//gcc -O2 -fopenmp test.c
//or
//gcc -O2 -mavx -fopenmp test.c
#include <string.h>
#include <stdio.h>
#include <x86intrin.h>
#include <omp.h>
#define N 1000000
#define R 1000
void mul(double *a, double *b) {
for (int i = 0; i<N; i++) a[i] *= b[i];
}
int main() {
double *a = (double*)_mm_malloc(sizeof *a * N, 32);
double *b = (double*)_mm_malloc(sizeof *b * N, 32);
//b must be initialized to get the correct bandwidth!!!
memset(a, 1, sizeof *a * N);
memset(b, 1, sizeof *b * N);
double dtime;
const double mem = 3*sizeof(double)*N*R/1024/1024/1024;
const double maxbw = 34.1;
dtime = -omp_get_wtime();
for(int i=0; i<R; i++) mul(a,b);
dtime += omp_get_wtime();
printf("time %.2f s, %.1f GB/s, efficency %.1f%%\n", dtime, mem/dtime, 100*mem/dtime/maxbw);
_mm_free(a), _mm_free(b);
}
FWIW Tôi nhận được khoảng 0,8 cho cả hai trên CPU Haswell 2,6 GHz di động thấp, biên dịch bằng tiếng kêu. –
@PaulR, cảm ơn bạn đã kiểm tra. Tôi có thể kiểm tra nó sau này trên hệ thống Haswell của tôi. Tôi nhận được kết quả lạ trên hệ thống Skylake của tôi mà tôi không nhận được trên Haswell vì vậy tôi sẽ không ngạc nhiên. –
@PaulR, tôi đã tìm ra!'__asm__ __volatile__ (" vzeroupper ":::);' ngay sau khi các cuộc gọi đến 'omp_get_wtime()' sửa chữa nó. –