2012-01-19 28 views
10

xem xét mảnh này rất đơn giản mã:Tại sao cùng một mã thực hiện nhanh hơn trong chuỗi?

uses Diagnostics; 

const 
    ITER_COUNT = 100000000; 

procedure TForm1.btn2Click(Sender: TObject); 
var 
    val: Double; 
    i: Integer; 
begin 
    sw := TStopwatch.StartNew; 

    val := 1; 
    for i := 0 to ITER_COUNT - 1 do 
    begin 
    val := val + i; 
    val := val - i; 
    val := val * 10; 
    val := val/10; 
    end; 

    sw.Stop; 

    mmo1.Lines.Add(Format('Simple completed in %D ms. Result: %G', 
    [sw.ElapsedMilliseconds, val])); 
end; 

vòng lặp đơn giản này thực hiện trong ms trên máy tính của tôi. Bây giờ nếu tôi viết cùng mã, chỉ sử dụng chủ đề khác nhau:

procedure TForm1.btn3Click(Sender: TObject); 
begin 
    sw := TStopwatch.StartNew; 
    TThread.CreateAnonymousThread(
    procedure 
    var 
     val: Double; 
     i: Integer; 
    begin 
     val := 1; 
     for i := 0 to ITER_COUNT- 1 do 
     begin 
     val := val + i; 
     val := val - i; 
     val := val * 10; 
     val := val/10; 
     end; 

     sw.Stop; 

     TThread.Queue(nil, procedure 
     begin 
      mmo1.Lines.Add(Format('Async completed in %D ms. Result: %G', 
      [sw.ElapsedMilliseconds, val])); 
     end); 
    end 
).Start; 
end; 

Phương pháp này mà không giống nhau nhưng trong các chủ đề khác nhau thực hiện trong ms! (Biên dịch trong Delphi XE với Release cấu hình hoạt động) Tôi nhận thấy ~ 25% đạt được trong thread không có vấn đề bao nhiêu lần lặp lại tôi có. Tại sao điều này là như vậy? Nó không phải là kết quả tương tự?

EDIT: Sau khi điều tra thêm, tôi thấy rằng có lẽ lý do cho điều này là hệ điều hành Windows 7. Trên máy chủ Windows 7, vòng lặp đơn giản trong chuỗi chính thực hiện chậm hơn 25% so với phiên bản không đồng bộ! Tôi thậm chí đã cố gắng chạy cùng một dự án này trên cùng một máy tính Windows 7 sử dụng chế độ Windows XP và sau đó cả hai kết quả đều bằng nhau - ~ 3000ms! Tôi hoàn toàn bị mất ở đây ... Windows 7 đang làm gì với chủ đề chính mà nó chậm hơn?

+0

Không thể sao chép, thời gian thực hiện giống nhau đối với máy tính xách tay của tôi (~ 2600 ms). – kludg

+0

Không có sự khác biệt cho tôi. 1947 và 1949 ms trên máy tính của tôi nhưng khi tôi vẫn đang sử dụng Delphi 5 làm môi trường phát triển chính của mình, tôi đã học được một số điều mới, +1 cho điều đó. –

+0

Trong hệ điều hành nào bạn đã thực hiện các bài kiểm tra của mình? – Linas

Trả lời

12

Thật kỳ lạ, nhưng có thể đó là do một số bù đắp c.q. căn chỉnh.

Có thể các biến trong chuỗi ẩn danh được căn chỉnh phù hợp và biến khác không được căn chỉnh. Bạn có thể thử thêm một số biến giả để thay đổi để bù đắp hoặc nếu bạn có Delphi XE2, hãy thử một số khác nhau code alignment.

+0

Tôi quản lý để làm chậm phiên bản đầu tiên nhiều hơn với các biến giả (~ 5000 ms trong một số thử nghiệm), không thể làm cho nó nhanh hơn ~ 4000ms ... Nhưng điều này không ảnh hưởng đến phiên bản async ... – Linas

+0

@Linas Make chắc chắn rằng 'val' luôn được căn chỉnh trên một ranh giới 8 byte. Ví dụ, phân bổ nó với một cuộc gọi đến GetMem hơn là trên ngăn xếp. –

+0

@DavidHeffernan Điều đó đã thực hiện các trick. Nếu tôi tự căn chỉnh biến 'Double' của mình với vòng lặp' GetMem' thực hiện như mong đợi. Câu hỏi đặt ra là tại sao Delphi thực hiện điều này một cách chính xác trong chuỗi ẩn danh riêng biệt nhưng không phải trong chuỗi chính? – Linas

Các vấn đề liên quan