[英]Code Optimization, C code not Responding to Cache Blocking
我正在上一个类的项目,该类让我们优化了C代码。 但是,我们在其上运行代码的服务器似乎不能很好地响应通常的优化技术,或者至少对我们所教过的技术没有很好的响应。 该作业建议使用代码移动,循环展开和阻塞。 以下是一些结构定义:
#ifndef _DEFS_H_
#define _DEFS_H_
#include <stdlib.h>
#define RIDX(i,j,n) ((i)*(n)+(j))
typedef struct {
char *team;
char *name1, *email1;
char *name2, *email2;
} team_t;
extern team_t team;
typedef struct {
unsigned short red;
unsigned short green;
unsigned short blue;
} pixel;
typedef void (*lab_test_func) (int, pixel*, pixel*);
void smooth(int, pixel *, pixel *);
void rotate(int, pixel *, pixel *);
void register_rotate_functions(void);
void register_smooth_functions(void);
void add_smooth_function(lab_test_func, char*);
void add_rotate_function(lab_test_func, char*);
#endif /* _DEFS_H_ */
这是我目前正在使用的功能,可将图像旋转90度:
char naive_rotate_descr[] = "naive_rotate: Naive baseline implementation";
void naive_rotate(int dim, pixel *src, pixel *dst)
{
int i, j;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++)
dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];
}
这是基准的低效实施。
char rotate_descr[] = "rotate: Current working version";
void rotate(int dim, pixel *src, pixel *dst)
{
int i, j;
int ii, jj;
int dim_min_one = dim - 1;
for (i = 0; i < dim; i+=8){
for (j = 0; j < dim; j+=8){
for(ii = 0; ii < 8; ii++){
for(jj = 0; jj < 8; jj+=8){
dst[RIDX(dim_min_one-(jj+j), (i+ii), dim)] = src[RIDX((i+ii), (j+jj), dim)];
dst[RIDX(dim_min_one-(jj+j+1), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+1), dim)];
dst[RIDX(dim_min_one-(jj+j+2), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+2), dim)];
dst[RIDX(dim_min_one-(jj+j+3), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+3), dim)];
dst[RIDX(dim_min_one-(jj+j+4), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+4), dim)];
dst[RIDX(dim_min_one-(jj+j+5), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+5), dim)];
dst[RIDX(dim_min_one-(jj+j+6), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+6), dim)];
dst[RIDX(dim_min_one-(jj+j+7), (i+ii), dim)] = src[RIDX((i+ii), (j+jj+7), dim)];
}
}
}
}
}
这是阻止和展开的组合。
char rotate1_descr[] = "rotate1: Simple 16 blocking";
void rotate1(int dim, pixel *src, pixel *dst)
{
int i, j;
int ii, jj;
int dim_min_one = dim - 1;
for (i = 0; i < dim; i+=16){
for (j = 0; j < dim; j+=16){
for(ii = 0; ii < 16; ii++){
for(jj = 0; jj < 16; jj++){
dst[RIDX(dim_min_one-(jj+j), (i+ii), dim)] = src[RIDX((i+ii), (j+jj), dim)];
}
}
}
}
}
这仅仅是阻塞。 现在,正在对其进行代码测试的服务器中具有24个Intel®Xeon®X5660 @ 2.80GHz CPU。 测试代码为阻塞和展开循环提供了1.2的加速,为简单阻塞提供了1.4的加速。
在我自己的计算机上,该计算机为Core i7 2.7GHz,另一台学校服务器为1.9GHz的24个英特尔®至强®处理器E5-2420,阻塞和展开速度仅为1.9。
同样,在所有系统上,8和16的块大小似乎在性能上没有区别,但是32将对性能造成不利影响。
现在,另一台ES-2420具有15mb的缓存,而X5660具有12mb,但是我觉得这不足以使阻塞过多或使展开降低性能的效果相形见war。 我真的在网上找不到任何有关X5660的优化及其良好响应的技术的信息。 所以我的问题是,处理器的哪些差异会导致对缓存阻塞的响应有如此大的差异,我还能从这种差异中拿出什么来编写在其上运行更好的代码? 教科书和讲座并没有真正为我提供解决这些问题的工具,因为他们建议的所有技术都无法与我们必须在其上运行的服务器配合使用。
如果可以在每台计算机上安装oprofile ,则可以测量高速缓存未命中率和其他有趣的参数,以确定为什么在每台计算机上获得不同的加速。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.