AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi 64 Speicherfragen

Ein Thema von BigAl · begonnen am 6. Feb 2014 · letzter Beitrag vom 19. Feb 2014
Antwort Antwort
Seite 2 von 2     12   
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#11

AW: Delphi 64 Speicherfragen (Memory Mapped Files)

  Alt 19. Feb 2014, 19:59
Hallo zusammen,

ich habe noch eine Frage zu dem Thema Memory Mapped Files. Ich habe mir ein Objekt gebaut, um die verschiedenen Matrizen im MMF zu bearbeiten. Das funktioniert echt super. Ich kann den Speicher von/zu Platte streamen und auf die diversen Elemente zugreifen. Ich möchte nun das Ganzen noch etwas tunen, da ich wie gesagt teilweise sehr viele Zugriffe habe. Speziell beim Lösen von linearen Gleichungssystem mittels Gauss finden extrem viele Zugriffe statt. Da werden aus jeder Nanosekunde gleich mehrere Minuten.

Folgende Zugriffe habe ich erstellt und möchte ich optimieren:

Delphi-Quellcode:
function TMatrixMMF<T>.GetValue(Y, X: Cardinal): T;
// Wert lesen
type
  P = ^T;
begin
  Result := P(UInt64(FMMFPtr) + (Y * FCountX + X) * SizeOf(T))^;
end;

procedure TMatrixMMF<T>.SetValue(Y, X: Cardinal; const Value: T);
// Wert schreiben
type
  P = ^T;
begin
  P(UInt64(FMMFPtr) + (Y * FCountX + X) * SizeOf(T))^ := Value;
end;
FMMPtr ist die Startadresse des MMF-Speichers. FCountX ist die Breite der Matrix.

Ich habe mir das Ganze mal im Assembler angeschaut und etwas potential entdeckt. Leider will Delphi XE5 keinen Inline-Assembler im 64-bit Code??? Meine Idee wäre folgende gewesen:

Nach jeder Teiloperation wird eine Bereichsprüfung auf die Variable durchgeführt. Auf diese würde ich gerne verzichten, da ein Überlauf eigentlich nicht möglich ist. Hat irgendwer vielleicht eine Idee wie man das sonst noch was rauskitzeln könnte? "inline" habe ich schon gemacht, bringt aber nicht viel...

Bin für jeden Tipp dankbar.

So long

Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:06
Kann man die Bereichsprüfung nicht in den Projektoptionen deaktivieren
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#13

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:14
Kann man die Bereichsprüfung nicht in den Projektoptionen deaktivieren
Die sind natürlich deaktiviert ({$R-}). Das ändert aber nichts daran, dass der vom Compiler erzeugte Assembler-Code nach jeder Operation eine Prüfung durchführt:

Delphi-Quellcode:
glbMatrix.pas.126: P(UInt64(FMMFPtr) + (Y * FCountX + X) * SizeOf(T))^ := Value;
0000000000759DD8 488B4D30 mov rcx,[rbp+$30]
0000000000759DDC 488B5530 mov rdx,[rbp+$30]
0000000000759DE0 8B4538 mov eax,[rbp+$38]
0000000000759DE3 F76208 mul dword ptr [rdx+$08]
0000000000759DE6 7305 jnb {glbMatrix}TMatrixMMF<System.Double>.SetValue + $2D
0000000000759DE8 E87319CBFF call @IntOver
0000000000759DED 034540 add eax,[rbp+$40]
0000000000759DF0 7305 jnb {glbMatrix}TMatrixMMF<System.Double>.SetValue + $37
0000000000759DF2 E86919CBFF call @IntOver
0000000000759DF7 8BC0 mov eax,eax
0000000000759DF9 486BC008 imul rax,rax,$08
0000000000759DFD 7105 jno {glbMatrix}TMatrixMMF<System.Double>.SetValue + $44
0000000000759DFF E85C19CBFF call @IntOver
0000000000759E04 488B4918 mov rcx,[rcx+$18]
0000000000759E08 4803C8 add rcx,rax
0000000000759E0B 7305 jnb {glbMatrix}TMatrixMMF<System.Double>.SetValue + $52
0000000000759E0D E84E19CBFF call @IntOver
0000000000759E12 488B4548 mov rax,[rbp+$48]
0000000000759E16 488901 mov [rcx],rax
Die Idee wäre halt gewesen die jnbs etc. und calls zu entfernen...

Gruß
Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#14

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:34
Wenn man viel RAM und ein 64Bit-BS hat, kann man das Programm-Limit von 2GB höher setzen.
Das geht bei 32Bit- und 64Bit-EXE.

Zitat:
This program demonstrates how to use up to 2.5 GB of RAM on the 32bit versions of Windows XP Prof. and Server 2003 and up to 3.5 GB of RAM on the 64bit versions of Windows XP, Vista, Server 2003 and 2008. This is accomplished by instructing the Delphi linker to set the IMAGE_FILE_LARGE_ADDRESS_AWARE flag set in the EXE header of the 32bit app.
http://cc.embarcadero.com/Item/24309

Dafür braucht man nur eine Directive im .DPR-File:

Delphi-Quellcode:
program Project2;

uses
  Vcl.Forms,
  Unit2 in 'Unit2.pas{Form2};

const
IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
var
   p: Pointer;
   n: Int64;
begin
   p := Pointer($D0000000);
//= 3.489.660.928, Above the 2GB line; and the 3GB line!

   p := VirtualAlloc(p, 1024, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
   if p = nil then
      RaiseLastWin32Error;

   n := Cardinal(p);
   Label1.Caption:= IntToHex(n, 16);
end;

end.

Geändert von hathor (19. Feb 2014 um 20:56 Uhr)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#15

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:42
Danke, aber das reicht leider nicht. Selbst meine Test-Matrizen haben schon 5 bis 6 GB... Im Endausbau sind die Teile schnell mal 100 oder mehr GB groß... Und ausgelagert dürfen die natürlich auch nicht werden, wegen dem Random-Access... Für den Start wird ist ein Rechne mit 64 GB Hauptspeicher geplant, der dann entsprechend den Anforderungen vergrößert wird. Win 8 kann ja bis 512 GB auf einer Maschine...

Gruß
Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#16

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:42
Die sind natürlich deaktiviert ({$R-}) ...
Delphi-Quellcode:
//...
0000000000759DE8 E87319CBFF call @IntOver
//...
Sieht aus, als ob das nicht die Bereichsprüfung, sondern die Integer-Overflow-Prüfung ist
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#17

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 20:47
Die sind natürlich deaktiviert ({$R-}) ...
Delphi-Quellcode:
//...
0000000000759DE8 E87319CBFF call @IntOver
//...
Sieht aus, als ob das nicht die Bereichsprüfung, sondern die Integer-Overflow-Prüfung ist
Guter Einwand . Danke, das war's.... Jetzt sieht das Ganze viel kompakter aus:

Delphi-Quellcode:
glbMatrix.pas.128: P(UInt64(FMMFPtr) + (Y * FCountX + X) * SizeOf(T))^ := Value;
0000000000759DA4 488B4510 mov rax,[rbp+$10]
0000000000759DA8 488B4018 mov rax,[rax+$18]
0000000000759DAC 488B4D10 mov rcx,[rbp+$10]
0000000000759DB0 8B5518 mov edx,[rbp+$18]
0000000000759DB3 0FAF5108 imul edx,[rcx+$08]
0000000000759DB7 035520 add edx,[rbp+$20]
0000000000759DBA 8BD2 mov edx,edx
0000000000759DBC 488B4D28 mov rcx,[rbp+$28]
0000000000759DC0 48890CD0 mov [rax+rdx*8],rcx
Hast Du noch so einen guten Tipp?

Vielen, vielen Dank!

Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#18

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 21:29
Hast Du noch so einen guten Tipp?
So einen guten nicht

Was mir allerdings auffällt, ist dass du den Zeiger auf ein Element an verschiedenen Stellen berechnest.
Im Allgemeinen lagere ich die Adress-/Index-Berechnung in eine inline-Methode aus (DRY), so dass man immer konsistent auf das Feld zugreift.
Fehler an dieser Stelle sind ziemlich tückisch

Geändert von BUG (19. Feb 2014 um 21:31 Uhr)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#19

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 21:37
Hast Du noch so einen guten Tipp?
So einen guten nicht

Was mir allerdings auffällt, ist dass du den Zeiger auf ein Element an verschiedenen Stellen berechnest.
Im Allgemeinen lagere ich die Adress-/Index-Berechnung in eine inline-Methode aus (DRY), so dass man immer konsistent auf das Feld zugreift.
Fehler an dieser Stelle sind ziemlich tückisch
Hmm. Die Berechnung an sich ist ja recht simpel und ändert sich eigentlich auch nie... Man könnte diese natürlich entsprechend auslagern. Aber sie findet ja nur genau zweimal statt...

Trotzdem Danke!

Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#20

AW: Delphi 64 Speicherfragen

  Alt 19. Feb 2014, 23:34
Ich denke, dass du vor allem auf gute Lokalität achten musst. Bei der Lösung solltest du also eben nicht wild durch die Gegend dereferenzieren, sondern die Matrix in Teile teilen und dann lösen.
Vorteil vom Partitionieren siehe hier die blaue Kurve: http://stackoverflow.com/q/4300663
Was da mathematisch passiert: http://math.stackexchange.com/questi...ices-in-pieces

Falls es geht, solltest du eine aktuelle Intel-CPU hernehmen und die Intel-MKL einsetzen. Die Intel-MKL diskriminiert gegen AMD-CPUs, aber auf einer Intel-CPU macht die so ziemlich alles platt. Das gilt aber natürlich nur, falls die CPU nicht gerade auf die SSD werten muss. Bei dir spielt ja anscheinend nicht nur die Lokalität RAM<>Cache eine Rolle, sondern auch die (viel krassere) Latenz SSD<>RAM.
http://www.kerrywong.com/2009/03/07/...formance-in-c/

Soweit ich weiß, ist die Intel-MKL aber nur in C verfügbar. Vielleicht kannst du dir ja eine DLL mit Subroutinen erzeugen und in Delphi benutzen...

Geändert von jfheins (19. Feb 2014 um 23:37 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz