Liên quan đến số other question của tôi, bây giờ tôi đã sửa đổi bộ giải mã ma trận thưa thớt để sử dụng phương pháp SOR (Kế thừa thư giãn). Mã bây giờ được như sau:Tại sao tốc độ của bộ giải SOR này phụ thuộc vào đầu vào?
void SORSolver::step() {
float const omega = 1.0f;
float const
*b = &d_b(1, 1),
*w = &d_w(1, 1), *e = &d_e(1, 1), *s = &d_s(1, 1), *n = &d_n(1, 1),
*xw = &d_x(0, 1), *xe = &d_x(2, 1), *xs = &d_x(1, 0), *xn = &d_x(1, 2);
float *xc = &d_x(1, 1);
for (size_t y = 1; y < d_ny - 1; ++y) {
for (size_t x = 1; x < d_nx - 1; ++x) {
float diff = *b
- *xc
- *e * *xe
- *s * *xs - *n * *xn
- *w * *xw;
*xc += omega * diff;
++b;
++w; ++e; ++s; ++n;
++xw; ++xe; ++xs; ++xn;
++xc;
}
b += 2;
w += 2; e += 2; s += 2; n += 2;
xw += 2; xe += 2; xs += 2; xn += 2;
xc += 2;
}
}
Bây giờ điều lạ là: nếu tôi tăng omega
(yếu tố thư giãn), tốc độ thực thi bắt đầu phụ thuộc đáng kể trên các giá trị bên trong các mảng khác nhau!
Đối với omega = 1.0f
, thời gian thực hiện ít nhiều liên tục. Đối với omega = 1.8
, lần đầu tiên, thường mất khoảng 5 mili giây để thực thi step()
10 lần này, nhưng điều này sẽ dần dần tăng lên gần 100 ms trong khi mô phỏng. Nếu tôi đặt omega = 1.0001f
, tôi thấy mức tăng thời gian thực hiện tương đối nhỏ; cao hơn omega
đi, thời gian thực hiện nhanh hơn sẽ tăng lên trong quá trình mô phỏng.
Vì tất cả điều này được nhúng bên trong bộ giải dịch, thật khó để có được một ví dụ độc lập. Nhưng tôi đã lưu trạng thái ban đầu và chạy lại trình giải quyết trên trạng thái đó mỗi bước, cũng như giải quyết cho bước thời gian thực tế. Đối với trạng thái ban đầu, nó nhanh, các bước thời gian tiếp theo tăng chậm hơn. Vì tất cả đều khác nhau, điều đó chứng minh rằng tốc độ thực thi của mã này phụ thuộc vào các giá trị trong sáu mảng đó.
Điều này có thể sao chép trên Ubuntu bằng g ++, cũng như trên Windows 7 64 bit khi biên dịch cho 32 bit với VS2008.
Tôi nghe nói rằng giá trị NaN và Inf có thể chậm hơn đối với các phép tính điểm động, nhưng không có NaN hoặc Inf. Có thể là tốc độ của tính toán nổi nếu không phụ thuộc vào giá trị của các số đầu vào?
Bạn có chắc chắn rằng bạn không đo lường một số thuật toán mã khác phụ thuộc vào giá trị của các phép tính không? – ebo
Nếu bạn tiếp tục gặp sự cố về hiệu suất, hãy xem xét sử dụng GPU cho các tính toán này. GPU là rất tốt ở công việc ma trận thưa thớt. – Mark
@ebo: Tôi đã sử dụng đồng hồ thời gian thực trong Linux để chỉ đo cuộc gọi này. Vì vậy, có, tôi khá chắc chắn. – Thomas