package combine;
import java.util.Random;
/**
* csapp优化程序性能从不同角度
* @author Administrator
*
*/
public class Combine {
static double combine1(Data data) {//初始版本
data.sum[0]=1;
for (int i = 0; i < data.a.length; i++) {
double val;
val = data.getElement(data, i);
data.sum[0]=data.sum[0]+val;
}
return 0;
}
static double combine2(Data data) {//用l替代data.a.length
data.sum[1]=1;
int l = data.a.length;
for (int i = 0; i < l; i++) {
double val;
val = data.getElement(data, i);
data.sum[1]=data.sum[1]+val;
}
return 0;
}
static double combine3(Data data) {//用double a[]存储data.a
data.sum[2]=1;
int l = data.a.length;
double a[] = data.a;
for (int i = 0; i < l; i++) {
data.sum[2]=data.sum[2]+a[i];
}
return 0;
}
static double combine4(Data data) {//data.sum[0]替换成s
data.sum[3]=1;
int l = data.a.length;
double a[] = data.a;
double s = 1;
for (int i = 0; i < l; i++) {
s+=a[i];
}
data.sum[3] = s;
return 0;
}
static double combine5(Data data) {//循环展开
int l = data.a.length;
int limit = l-1;
double a[] = data.a;
double s = 1;
int i = 0;
for (; i < limit; i+=2) {
s=(s+a[i])+a[i+1];
}
for (; i < l; i++) {
s=s+a[i];
}
data.sum[4] = s;
return 0;
}
static double combine6(Data data) {//多个累计变量
int l = data.a.length;
int limit = l-1;
double a[] = data.a;
double s1 = 1;
double s2 = 0;
int i = 0;
for (; i < limit; i+=2) {
s1 = s1 + a[i];
s2 = s2 + a[i+1];
}
for (; i < l; i++) {
s1=s1+a[i];
}
data.sum[5] = s1+s2;
return 0;
}
static double combine7(Data data) {//重新结合变换
double d[]=data.a;
int l = d.length;
int limit = l-1;
double s=1;
int i = 0;
for (; i < limit; i+=2) {
s=s+(d[i]+d[i+1]);//d[i]+d[i+1]和s累加可并行
}
for (; i < l; i++) {
s+=d[i];
}
data.sum[6]=s;
return s;
}
public static void main(String[] args) {
int n = 300000000;
Data data = new Data(n);
CalTime.start();
combine1(data);
long t1 = CalTime.end();
CalTime.start();
combine2(data);
long t2 = CalTime.end();
CalTime.start();
combine3(data);
long t3 = CalTime.end();
CalTime.start();
combine4(data);
long t4 = CalTime.end();
CalTime.start();
combine5(data);
long t5 = CalTime.end();
CalTime.start();
combine6(data);
long t6 = CalTime.end();
CalTime.start();
combine7(data);
long t7 = CalTime.end();
for (int i = 0; i < data.sum.length; i++) {
System.out.println(data.sum[i]);
}
System.out.println(t1+" "+t2+" "+t3+" "+t4+" "+t5+" "+t6+" "+t7);
}
}
存储随机数的Data类:
package combine;
import java.util.Random;
public class Data {
double a[];
double sum[];
public Data(int n) {
Random random = new Random(System.currentTimeMillis());
a = new double[n];
sum = new double[7];
for (int i = 0; i < n; i++) {
a[i] = random.nextInt(n);
}
}
double getElement(Data data,int index){
if(index<0||index>=data.a.length){
return 0;
}
return data.a[index];
}
}
计算时间类:
package combine;
public class CalTime {
private static long timeStart;
public static void start() {
timeStart = System.currentTimeMillis();
}
public static long end(){
return System.currentTimeMillis()-timeStart;
}
}
多次运行得到运行时间:t1~t7:
290 288 284 277 276 198 194 289 284 282 275 277 195 192
289 284 282 281 277 194 191
可以看到加速比在n=300000000下才在1.51这样。。。。
书上用c可以从combine1的10CPE(每元素周期)下降到combine7的0.8CPE,
不懂哪里不对。。
转载请注明原文地址: https://ju.6miu.com/read-4418.html