Autor Beitrag
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mo 18.08.14 14:20 
Hallo,

Mist, die sind schon viel weiter, im April dachte ich mal an BCD Arithmetik,..ich bin alt...
www.dolbeau.name/dolbeau/p196/p196_mpi.pdf
www.isc-events.com/i...ter_Swierczewski.pdf

Eigentlich wollte ich noch mal testen, wie viele Stellen man als Schutzstellen braucht.
Ich nehme zum Beispiel nur die ersten 1000 Stellen von vorn/hinten und bestimme damit die Anzahl der Berechnungen bis zum Überlauf.Damit wollte ich dann die mittleren threads rechnen lassen.
Es war doch im Mittel alle 2,41... ein Überlauf, wenn ich mit 2* 7500 Stellen pro Thread Abschnitt rechnen will und 50 zusätzliche Stellen berechnen möchte( ~ 50*2,4~ 120 Durchläufe ), muss ich die Abfolge der Überläufe kennen, weil sich ja dann die oberste Stelle um 1 verschiebt und die Anzahl an Schutzstellen, das da kein Spökes/Unsinn rauskommt.
Wenn A/B der Kernberech den ich berechnen will ist, möchte ich V/W wissen, den ich mitschleppen muss:
....VVAAAAAAVV.......Mitte.......WWBBBBBBWW....-> VVAAAAAAVVWWBBBBBBWW also dicht beisammen.
Aber das habe ich noch nicht getestet.
Die Schreiben in ihrer Abhandlung, dass die Speichergeschwindigkeit beim Einsatz von SSE Berechnung bremst ( Die Addition wird schon "normal" gebremst ) deshalb mein Gedanke, es möglichst im Level I Cache zu belassen und möglichst wenig zu synchronisieren.
Momentan kommen sie nicht über 1,4E10 Stellen/Sekunde ab 6 Threads und SSE4 :D
Die hätten das mal genauer benennen sollen. 1 Byte Additionen + Carry Berechnungen ( Für die ersten 1 Mio Stellen brauchte es bei mir 604,2x1E9 Berechnungen und es dauerte 1000 Sekunden = 23 mal langsamer :-( ( Selbst bei optimalen 6 Threads ein Faktor 4 ).

Gruß Horst
EDIT:
Die angehängte Datei war die falsche Version...
Edit2:
Darum ging es, assembler Varinaten die direkt 4-er Gruppen verarbeiten.
Zum Schluss werden die restlichen Byte per Pascal berechnet

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
function NumAddAs(pDigit1,pDigit2 : tpDigit):NativeUInt;
//Mal sehen, ob moeglichst viele Register helfen
//Aber es dauert so auch etwa 0.25..0.32 Takte/Digit oder war das bei 64Bit??
//4er-Gruppe Laden und umsortieren mit Bwap-> 
//mit Gegestelle addieden->dort speichern und 
//umsortieren und wieder am Original speichern

//[p1]ABCD -> DCBA -> DCBA+ [p2]VWXY = DV CW BX AY -> Speichern[p2] und  DV CW BX AY -> AY BX CW DV  speichern[p1]
begin
  asm
//   PUSH     ECX; PUSH     ESI;PUSH   EDI;
// Bei dermaszen vielen Stellen geht das unter.
     PUSHAD

     MOV     ESI,pDigit2
     MOV     EDI,pDigit1

     MOV     ECX,ESI
     SUB     ECX,EDI
     INC     ECX
     SAR     ECX,3
     TEST    ECX,ECX
     MOV     @result,ECX;
     JLE     @UndTschuesz
//EDI von Byte auf LongWord zeigen lassen
     SUB     ESI,3

     CMP     ECX,4
     JLE     @Reste

@WeiteSchritte:
     SUB     ECX,4

     MOV     EAX,[ESI]
     BSWAP   EAX
     MOV     EBX,[ESI-4]
     BSWAP   EBX
     ADD     EAX,[EDI]
     MOV     EBP,[ESI-8]
     BSWAP   EBP
     ADD     EBX,[EDI+4]
     MOV     EDX,[ESI-12]
     BSWAP   EDX
     ADD     EBP,[EDI+8]
     ADD     EDX,[EDI+12]

     MOV     [EDI],EAX
     BSWAP   EAX
     MOV     [EDI+4],EBX
     BSWAP   EBX
     MOV     [EDI+8],EBP
     BSWAP   EBP
     MOV     [EDI+12],EDX
     BSWAP   EDX

     ADD     EDI,16

     MOV     [ESI],EAX
     MOV     [ESI-4],EBX
     MOV     [ESI-8],EBP
     MOV     [ESI-12],EDX

     SUB     ESI,16
     CMP     ECX,4

     JG      @WeiteSchritte;

@Reste:
     MOV     EAX,[EDI]
     BSWAP   EAX
     MOV     EDX,[ESI]
     ADD     EAX,EDX
     MOV     EDX,EAX
     BSWAP   EDX
     MOV     [ESI],EAX
     SUB      ESI,4
     MOV     [EDI],EDX
     ADD      EDI,4
     DEC     ECX
     JNE     @Reste;

@UndTschuesz:
     POPAD
//     POP     EDI; POP     ESI;POP     ECX
  end;
end

function CalcCarryAs(var a:tDigit2;cnt:NativeInt):NativeInt;assembler;
//Soll die Ueberträge/Carry von 8 Digits bestimenn {Minimum 8 Byte}
//Anaolg zu BCD-Add
//http://www.azillionmonkeys.com/qed/asmexample.html
//Norbert Juffa has given me some devilishly
//clever code for performing a 64 bit BCD addition
//statt lea   edi, [eax+66666666h]
//eben Byte-weise
//MOV  EDX,EAX
//ADD  EDX,246*($01010101)// $F6F6F6F6 // OK LEA EDX,[EAX+$F6F6F6F6] ginge auch
  asm
  PUSH EDI
  PUSH ESI
  PUSH EBX
  PUSH ECX
  PUSH EBP

  MOV  EDI,a
  XOR  EAX,EAX   // Carry = 0;
  MOV  ESI,cnt
  SUB  ESI,8
// Uberhaupt etwas zu tun? Minimum 8 Byte
  JL   @WarWohlNichts

@Loop:
  ADD  EAX,[EDI] // Carry einarbeiten
  MOV  EBP ,[EDI+4]
  SUB  ESI,8
  MOV  EDX,EAX
  ADD  EDX,246*($01010101)
  SBB  EBX,EBX  // Carry merken
  XOR  EAX,EDX
  AND  EAX,$01010101
  ADD  EBX,EBX
  ADC  EBP,0    // auf folgende Zahl uebetragen
  SHL  EBX,1
  MOV  ECX,EBP
  RCR  EAX,8    // Carry reinrollen
  ADD  ECX,246*($01010101)

  XOR  EAX,($01010101)
  IMUL EAX,EAX,246
  SUB  EDX,EAX
  MOV  [EDI], EDX

  SBB  EAX,EAX  // Carry merken
  XOR  EBP,ECX
  AND  EBP,($01010100)
  ADD  EAX,EAX
  RCR  EBP,8 // Carry reinrollen
  XOR  EBP,($01010101)
  IMUL EBP,EBP,246
  SUB  ECX,EBP
  MOV  [EDI+4], ECX

  SHR  EAX,31
  ADD  EDI,8
  TEST ESI,ESI
  JGE  @Loop

@WarWohlNichts:
  POP  EBP
  POP  ECX
  POP  EBX
  POP  ESI
  POP  EDI
end;