Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Bitmanipulation


gerd99 - Di 05.05.20 22:28
Titel: Bitmanipulation
Hallo

ich möchte gerne von einer 64 Bit-Kette ein paar bits verschieben,

ich möchte das 10 bit an erster Stelle
das 18 bit an zweiter Stelle
das 26 an dritter Stelle

Wichtig sind mir die ersten 8 Stellen, der Rest ist dann egal.

wie macht man das am schnellsten.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function Bittest (TestZahl : uint64; Bitnr: uint64):boolean;
begin
    Result := (testzahl and (uint64(1shl bitnr)) <> 0;
end;

procedure BitSet(var TestZahl :uint64; bitnr:uint64);
begin
    TestZahl:= testzahl OR (uint64(1shl BitNr);
end;

var zahl,b:uint64;
b:=0;
zahl:=389282;

if bittest(zahl,10then bitset(b,0);
if bittest(zahl,18then bitset(b,1);
if bittest(zahl,26then bitset(b,2);
usw.


da muss es doch eine schnellere Methode geben? Aber mit shl verschiebe ich alles und ich möchte praktische einzelne bit in der mitte umd x nach links verschieben.


Narses - Mi 06.05.20 09:12

Moin!

Es klingt nicht besonders gut geplant, was du vor hast (ohne genau zu wissen, was du da tust, reines Bauchgefühl). :? Wenn du doch nur 3 Bits "brauchst", warum nimmst du dann nicht gleich die Bits 0, 1 und 2? Und vor allem, warum ausgerechnet ein 64-Bit-Int (für 3 Nutzbits)? :nixweiss: Aber egal, das war ja nicht gefragt. ;)

Du maskierst die Ziel-Stellen mit einer AND-Maske aus, verschiebst die Ziel-Bits, maskierst diese so, dass nur noch die Ziel-Stellen gesetzt sein können und übernimmst mit OR. Fertig. :idea:

cu
Narses


Ralf Jansen - Mi 06.05.20 10:57

Meine Delphi/Pascal Kenntnisse sind ein wenig eingerostet aber dein Code scheint die Bits zu kopieren nicht zu verschieben. Was willst du wirklich verschieben oder kopieren?


gerd99 - Mi 06.05.20 17:58


Delphi-Quelltext
1:
2:
3:
if bittest(zahl,10then bitset(zahl,0);
if bittest(zahl,18then bitset(zahl,1);
if bittest(zahl,26then bitset(zahl,2);


Ich mache es an einem Beispiel verständlich


00000000
01000000
01000000
00000000
01000000
01000000
01000000
01000000

Ich möchte den 10 an erster Stelle und den 18 an zweiter Stelle. Sieht dann so aus:

110111x
xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx
xxxxxxx

Und das genannte Verfahren von mir schien mir schneller zu gehen. Aber ich habe schon eine private Nachricht bekommen, die das Problem offensichtlich löst.

Gerd


gerd99 - Mi 06.05.20 19:58


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
test:=0;
  bitset(test,9);
  bitset(test,17);
  bitset(test,25);
   // 9
  test:= (Uint64(test)) or ((test shr 9and uint64(1)) or ((test shr 16and uint64(2)) or ((test shr 23and uint64(4));

  if bittest(test,0then
  memo2.Lines.Add('1');
  if bittest(test,1then
  memo2.Lines.Add('2');
  if bittest(test,2then
  memo2.Lines.Add('3');


Alle 3 bits sind an gewünschter Stelle. Eine Frage habe ich. Um wieviel ist das schneller als das Anfangsbeispiel. Oder es würde mir schon ausreichen, wenn
jemand sagen könnte, dass diese Methode schneller ist.


jfheins - Mi 06.05.20 21:07

user profile icongerd99 hat folgendes geschrieben Zum zitierten Posting springen:

Alle 3 bits sind an gewünschter Stelle. Eine Frage habe ich. Um wieviel ist das schneller als das Anfangsbeispiel. Oder es würde mir schon ausreichen, wenn
jemand sagen könnte, dass diese Methode schneller ist.

Diese letzte Methode ist wesentlich langsamer, da auf eine VCL Komponente zugegriffen wird. Wahrscheinlich mehr als einen Faktor 100.

Falls du es genau wissen musst, teste es am Besten selbst. Niemand kennt die Randbedingungen (CPU, Performance-Anforderungen) besser als du ;-)


gerd99 - Mi 06.05.20 21:19

die Zeile 8 - 13 mit der memo Ausgabe verwende ich natürlich nicht in meinem Programm.
Langsamer - wirklich?
Ja, ich teste das mal, wenn ich mit der eigentlichen Routine die ich gerade schreibe fertig bin.

Gerd


Narses - Mi 06.05.20 22:48

Moin!

user profile icongerd99 hat folgendes geschrieben Zum zitierten Posting springen:
Aber ich habe schon eine private Nachricht bekommen, die das Problem offensichtlich löst.
Wozu macht man sich eigentlich die Mühe, hier noch irgendwas zu schreiben... :gruebel: :( Und dann nichtmal darauf eingehen. :|

user profile icongerd99 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
if bittest(zahl,10then bitset(zahl,0);
if bittest(zahl,18then bitset(zahl,1);
if bittest(zahl,26then bitset(zahl,2);
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Meine Delphi/Pascal Kenntnisse sind ein wenig eingerostet aber dein Code scheint die Bits zu kopieren nicht zu verschieben.
@Ralf: Deine Kenntnisse sind offensichtlich nicht verrostet, das ist kein äquvalenter Code! :mahn:

user profile icongerd99 hat folgendes geschrieben Zum zitierten Posting springen:
Und das genannte Verfahren von mir schien mir schneller zu gehen.
Abgesehen davon, dass dein Code nicht das gleiche tut, ist er mit sicherheit langsamer, als das hier (was genau das ist, was ich beschrieben habe), da brauche ich keinen Profiler für: ;) (conditionals, jumps, stack, etc. ggü. bitmanipulations, die der Compiler in Register optimieren kann/könnte)

Delphi-Quelltext
1:
test:= (Uint64(test)) or ((test shr 9and uint64(1)) or ((test shr 16and uint64(2)) or ((test shr 23and uint64(4));                    

cu
Narses


gerd99 - Mi 06.05.20 23:14

Hallo Narses,

das mit der Bitmaske hast Du auch geschrieben. Ich konnte mir darunter im ersten Moment nur nichts vorstellen, wie du das genau meintest.
Schönen Abend

Gerd


Narses - Do 07.05.20 13:52

Moin user profile icongerd99!

user profile icongerd99 hat folgendes geschrieben Zum zitierten Posting springen:
das mit der Bitmaske hast Du auch geschrieben.
Jetzt versteh ich das erstmal... :autsch: :lol:

Es geht mir nicht darum oder gegen den Strich, ignoriert zu werden (das können andere eh viel besser :evil:), sondern um die "Lösung per PN". Wir sind hier in einem Forum, um Wissen zu verbreiten und nicht zu verstecken (per PN :roll:), das war der Grundgedanke. :idea:

cu
Narses


devOX96 - Mi 25.11.20 11:53

Auch von mir vielen Dank für die hilfreichen Antworten, hat mir sehr geholfen.