2012-01-19 23 views
10

bu kod çok basit bir parça düşünün:Neden aynı kod iş parçacığında daha hızlı yürütüyor?

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; 

Bu basit döngü benim PC'de ms yürütür. Aynı kod yazmak Şimdi, eğer sadece farklı iplik kullanarak:

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; 

aynısını yapar ama farklı bir iş parçacığı ms yürütür Bu yöntem! (Serbest bırakma yapılandırması etkinken Delphi XE'de derlendi) Fark ettim kaç tane iterasyon olursa olsun iplikte ~% 25 kazanç fark ettim. Neden böyle? Aynı sonuçlar olmamalı mıydı?

DÜZENLEME: Daha fazla araştırmadan sonra muhtemelen bunun nedeninin Windows 7 işletim sistemi olduğunu buldum. Windows 7'de ana iş parçacığı içinde basit döngü, async sürümden ~% 25 daha yavaş çalışır! Hatta aynı projeyi Windows XP modunu kullanarak aynı Windows 7 PC'de çalıştırmayı denedim ve her iki sonuç da eşittir - ~ 3000ms! Burada tamamen kayboldum ... Windows 7, ana iş parçacığı ile daha yavaş ne yapıyor?

+0

Yeniden üretilemiyor, yürütme süresi dizüstü bilgisayarımla aynı (~ 2600 ms). – kludg

+0

Benim için de fark yok. Makinemde 1947 ve 1949 ms'lar ama hala Delphi 5'i ana geliştirme ortamım olarak kullanıyorum, bunun için yeni şeyler öğrendim, bunun için +1. –

+0

Hangi işletim sisteminde test yaptınız? – Linas

cevap

12

Gerçekten garip ama belki de bazı ofset c.q. hizalaması.

Belki de adsız iş parçacığındaki değişkenler uygun şekilde hizalanmış, diğeri de değil. Ofset değiştirmek için bazı kukla değişkenler eklemeye çalışabilir veya Delphi XE2 varsa, farklı bir code alignment deneyin.

+0

Kukla değişkenler (bazı testlerde ~ 5000 ms) ile ilk sürümü daha da yavaşlatmayı başardım, ~ 4000 ms'den daha hızlı yapamıyorum ... Ama bu, uyumsuz versiyonu etkilemiyor ... – Linas

+0

@Linas Make val'nin her zaman bir 8 bayt sınırında hizalandığından emin olun. Örneğin, onu yığın yerine GetMem'e bir çağrı ile ayırın. –

+0

@DavidHeffernan Bu hile yaptı. Eğer "Double" değişkenimi "GetMem" döngüsü ile manuel olarak hizalarsam beklenen şekilde yürütülür. Soru şu ki Delphi bunu ana iş parçacığında değil, ayrı bir anonim iş parçacığında doğru olarak yapıyor? – Linas

İlgili konular