Tôi có một số mã java đơn giản mà tôi đã viết để sử dụng nhân tạo rất nhiều RAM và tôi thấy rằng khi tôi nhận được lần liên khi tôi sử dụng những lá cờ:Tại sao hạn chế hiệu suất tăng GC lên 1 luồng?
1029.59 seconds .... -Xmx8g -Xms256m
696.44 seconds ..... -XX:ParallelGCThreads=1 -Xmx8g -Xms256m
247.27 seconds ..... -XX:ParallelGCThreads=1 -XX:+UseConcMarkSweepGC -Xmx8g -Xms256m
Bây giờ, tôi hiểu tại sao -XX:+UseConcMarkSweepGC
tăng hiệu suất, nhưng tại sao tôi nhận được tăng tốc khi tôi hạn chế GC đơn luồng? Đây có phải là một tạo phẩm của mã java viết kém của tôi hay là cái gì đó sẽ áp dụng cho java được tối ưu hóa đúng cách?
Đây là mã của tôi:
import java.io.*;
class xdriver {
static int N = 100;
static double pi = 3.141592653589793;
static double one = 1.0;
static double two = 2.0;
public static void main(String[] args) {
//System.out.println("Program has started successfully\n");
if(args.length == 1) {
// assume that args[0] is an integer
N = Integer.parseInt(args[0]);
}
// maybe we can get user input later on this ...
int nr = N;
int nt = N;
int np = 2*N;
double dr = 1.0/(double)(nr-1);
double dt = pi/(double)(nt-1);
double dp = (two*pi)/(double)(np-1);
System.out.format("nn --> %d\n", nr*nt*np);
if(nr*nt*np < 0) {
System.out.format("ERROR: nr*nt*np = %d(long) which is %d(int)\n", (long)((long)nr*(long)nt*(long)np), nr*nt*np);
System.exit(1);
}
// inserted to artificially blow up RAM
double[][] dels = new double [nr*nt*np][3];
double[] rs = new double[nr];
double[] ts = new double[nt];
double[] ps = new double[np];
for(int ir = 0; ir < nr; ir++) {
rs[ir] = dr*(double)(ir);
}
for(int it = 0; it < nt; it++) {
ts[it] = dt*(double)(it);
}
for(int ip = 0; ip < np; ip++) {
ps[ip] = dp*(double)(ip);
}
double C = (4.0/3.0)*pi;
C = one/C;
double fint = 0.0;
int ii = 0;
for(int ir = 0; ir < nr; ir++) {
double r = rs[ir];
double r2dr = r*r*dr;
for(int it = 0; it < nt; it++) {
double t = ts[it];
double sint = Math.sin(t);
for(int ip = 0; ip < np; ip++) {
fint += C*r2dr*sint*dt*dp;
dels[ii][0] = dr;
dels[ii][1] = dt;
dels[ii][2] = dp;
}
}
}
System.out.format("N ........ %d\n", N);
System.out.format("fint ..... %15.10f\n", fint);
System.out.format("err ...... %15.10f\n", Math.abs(1.0-fint));
}
}
Chủ đề có phí. Nếu mã được viết theo cách như vậy mà nó sẽ không được hưởng lợi từ các chủ đề bổ sung, thêm chủ đề thực sự sẽ làm chậm nó xuống. Nếu tôi đã đoán, tôi muốn nói cho GC thêm chủ đề gây ra nó để mất nhiều hơn các chu kỳ đồng hồ của bộ vi xử lý của bạn, để lại ít hơn cho chương trình thực tế của bạn.Cho dù đây là một điều tốt hay không phụ thuộc hoàn toàn vào bản chất của chương trình đang được thực thi và sự cân bằng tốc độ/bộ nhớ cụ thể mà bạn đang cố gắng đạt được. –
GC vốn là một vấn đề một luồng. Nhiều chủ đề gây ra nhiều chi phí hơn: phải có một biểu đồ đối tượng lớn và rất nhiều bộ nhớ để lấy lại trước khi thêm chủ đề cải thiện hiệu suất vì bạn phải vượt qua chi phí đầu tiên đó. –
Đối với điểm chuẩn thực, không đủ để chạy mã của bạn chỉ một lần trong phương thức chính. Nếu không có giai đoạn khởi động và một số lần lặp lại để có được một giá trị trung bình và phương sai, các giá trị là vô nghĩa. – isnot2bad