Forum: FPGA, VHDL & Co. Spartan XC6SLX16, bei 100MHz schon Ende der Fahnenstange?


von Norbert (Gast)


Lesenswert?

Ich bin gerade dabei, eine etwas komplexere Logik auf meinem Nexys3 
auszutesten. Es handelt sich hier hauptsächlich um komplexe numerische 
Berechnungen (number crunching). Leider fängt ISE bereits bei 100MHz an, 
beim Place & Route Fehler beim Timing einzelner Abschnitte zu melden. 
Ich habe mal den SmartXplorer durchlaufen lassen um eventuell eine 
optimalere Strategie zu finden aber es bleibt dabei, ich bekomme schon 
bei 100MHz kein fehlerloses Timing mehr hin. Der Füllgrad der Logik 
liegt bei ziemlich genau 60%, was eigentlich optimal sein sollte.

Das Ganze läuft zwar in der Realität mit den 100MHz noch fehlerfrei aber 
das liegt wohl nur an den Toleranzen der Hardware, die in meinem Fall 
wohl willig ist, ein wenig mehr auszuhalten als ISE prophezeit.

Ich bin ein wenig erstaunt, dass hier schon bei 100MHz Schluß ist. Ist 
bei der Spartan6 Reihe (Speedgrade -2) nicht mehr drin?

Gruß, Norbert

von Mac G. (macgyver0815)


Lesenswert?

Norbert schrieb:
> die in meinem Fall
> wohl willig ist, ein wenig mehr auszuhalten als ISE prophezeit.

Bei Raumtemperatur. Über den ganzen spezifizierten Temperaturbereich 
(und alle möglichen Mondphasen ;-)) vermutlich nicht.


Ich glaube Du musst da noch ein paar Details zu Deinem konkreten Design 
posten...
Also z.B. hast Du da nur eine riesen kombinatorische Logik oder haste es 
gut gepipelined?

von Norbert (Gast)


Lesenswert?

Mac Gyver schrieb:
> Ich glaube Du musst da noch ein paar Details zu Deinem konkreten Design
> posten...
> Also z.B. hast Du da nur eine riesen kombinatorische Logik oder haste es
> gut gepipelined?

Naja, ich hatte gehofft, es nicht so konkret erwähnen zu müssen weil 
dann das Risiko groß ist, dass die Diskussion in einen für mich wenig 
zielführenden Bereich auf der Metaebene abgleitet. Es handelt sich um 
diese Geschichte hier:

https://github.com/fpgaminer/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/VHDL_Xilinx_Port

Um die Diskussion in die richtige Richtung zu lenken, es ging mir 
hierbei hauptsächlich um den akademischen Effekt. Für mich war 
hauptsächlich von Interesse wie diese Sache funktioniert. Mir ging es 
zunächst darum, den Code an mein Board anzupassen um mir das Ganze mal 
anzuschauen. Auch um die Frage, wieviel Leistung kann ich aus dem 
(kleinen!) FPGA meines Experimentierboards herausholen und kann ich den 
VHDL Code eventuell noch optimieren, so dass er noch effizienter läuft. 
Ich finde diese Sache, einen FPGA als "Rechenknecht" mit USB Interface 
am PC zu betreiben, grundsätzlich sehr interessant.

Um diese Geschichte (also Bitcoin Mining) im "finanziell 
gewinnbringenden" Bereich zu betreiben benötigt man FPGAs mit großem 
Logikvolumen und die entsprechende (kostenpflichtige) Software. Soviel 
schon mal vorneweg, falls das jemand wissen möchte. Ich habe nicht das 
Geld um in solch eine vage Sache zu investieren. Ich bin nur ein kleiner 
Hobbyist mit technischem Interesse.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> effizienter
Definiere "effizient".
Wenn dein Algorithmus mit 100MHz läuft, und du das Ganze 100 mal ins 
FPGA bekommst, ist es effizienter, als wenn der Algorithmus mit 300 MHz 
läuft, du aber nur 10 Instanzen ins FPGA bekommst...

von Norbert (Gast)


Lesenswert?

Lothar Miller schrieb:
> Definiere "effizient".
> Wenn dein Algorithmus mit 100MHz läuft, und du das Ganze 100 mal ins
> FPGA bekommst, ist es effizienter, als wenn der Algorithmus mit 300 MHz
> läuft, du aber nur 10 Instanzen ins FPGA bekommst...

Effizient in meinem Sinne wäre eine möglichst hohe Taktfrequenz bei 
optimaler Ausnutzung der vorhandenen Logikkapazität.

Man bekommt übrigens sinnvollerweise nur eine einzige Instanz in einen 
FPGA. Mehr macht keinen Sinn denn man kann, je nach vorhandener 
Logikkapazität, die Berechnungsschleife des SHA-256 Algorithmus mehr 
oder weniger "ausrollen" und das macht entsprechend viel aus. Im VHDL 
Code gibts einen entsprechenden Parameter dazu mit dem man das 
einstellen kann.

Soweit ich weiß, braucht man aber einen Virtex 7V2000T um die SHA 
Berechnung komplett entfalten zu können. Dann läuft das Ganze in "einem 
Atemzug" ab und man erhält richtig Performance. Allerdings kostet dieser 
FPGA schon soviel wie ein Mittelklasse-PKW. Da liegt das Optimum eher 
bei kleineren Bausteinen von denen man dann mehrere parallel rechnen 
läßt.

Aber bleiben wir doch mal im akademischen Bereich. Sind die 100MHz 
wirklich die Grenze des Spartan6? Oder wäre bei entsprechenden 
Randbedingungen mehr drin?

von Christian R. (supachris)


Lesenswert?

Bei 60% Füllgrad sind 100MHz meiner Erfahrung nach schon recht gut. Die 
Spartan 6 sind jetzt nicht die schnellsten.

von ehemaliger Spartanentwickler (Gast)


Lesenswert?

Ich habe einen Spartan 6 mit über 200MHz Grundfrequenz laufen lassen und 
der war auch voll. Man muss eben richtig bauen und das bezieht sich auf 
die geschickte Nutzung der Taktresourcen. Das ist das Problem des 
Spartan 6. Und man muss jeden Schaltungsteil anfassen und mit FFs 
vollbügeln.

Der Smartexplorer ist leider ziemlich unfähig und testet nur seine 
bekannten Optimierungsstrategien. Besser ist es, da Hand anzulegen und 
selber sich anzuschauen, wo es klemmt und das Timing mit FFs zu 
entspannen. Das registerretiming habe ich erst kürzlich wieder 
getestet:Obwohl ich eine riesen Bank an FFs hintergehängt hatte, hat das 
balancieren nichts gebraucht. Ich habe sie dann händisch verteilt - 
voi-la!

von Schlumpf (Gast)


Lesenswert?

Norbert schrieb:
> Aber bleiben wir doch mal im akademischen Bereich. Sind die 100MHz
> wirklich die Grenze des Spartan6? Oder wäre bei entsprechenden
> Randbedingungen mehr drin?

Die Grenze des Spartan ist dann erreicht, wenn du zwei Register ohne 
Logik dazwischen hintereinanderschaltest, diese manuell nebeneinander 
platzierst und dir dann die maximal erreichbare Taktfrequenz errechnen 
lässt.

Wenn es deine Logik aber erforderlich macht, dass du 30 LUTs zwischen 
den beiden Registern benötigst, dann ist eben schon viel früher Schluss.

Ganz akademisch gesagt liegt es an dir und wie clever du dein Design 
gestaltest, wo die ereichbare Taktrate liegen wird.

von Rosa-Kleidchen (Gast)


Lesenswert?

Das Design mit FFs zu entspannen, ist natuerlich ein Mittel der Wahl 
fuer ein ein synchrones Design. Ich bin schon etwas laenger draussen, 
aber ich habe frueher den Floorplaner verwendet, um zu gucken, wo die 
kritischen Pfade verlaufen, um dann gezielt zuhandeln. Trotzdem 100MHz 
ist schon arg wenig....
Rosa

von Norbert (Gast)


Lesenswert?

Schlumpf schrieb:
> Wenn es deine Logik aber erforderlich macht, dass du 30 LUTs zwischen
> den beiden Registern benötigst, dann ist eben schon viel früher Schluss.
>
> Ganz akademisch gesagt liegt es an dir und wie clever du dein Design
> gestaltest, wo die ereichbare Taktrate liegen wird.

Was mir persönlich an dem VHDL Code nicht so gut gefällt, ist der 
Umstand, dass hier die ganzen verschiedenen Bitschiebereien und 
-rotierereien der SHA Berechnung jeweils als einzelne Komponenten mit 
jeweiligen Bitmappings zwischen den Vektoren ausgeführt sind. Solche 
Optimierungen würden bei einem konventionellen Programm, das durch einen 
Prozessor abgearbeitet wird, Sinn machen aber ob sowas bei einem 
Logikdesign für einen FPGA die beste Wahl ist, da bin ich mir nicht so 
sicher. Ich vermute nämlich, dass hier die Wurzeln des Übels liegen, das 
eine höhere Taktfrequenz verhindert.

Ich spiele mit dem Gedanken, einen Barrel- oder Funnel-Shifter mit 
entsprechender Bitbreite in VHDL zu konstruieren (aufwendig aber 
effizient) und dafür diesen ganzen Komponentenkram rauszuwerfen. Leider 
habe ich selbst keinerlei Erfahrung auf dem Gebiet und kann nur 
Vermutungen darüber anstellen, wie man sowas am besten realisiert und 
was wirklich Geschwindigkeit in die Logik bringt. Aber es ist auf jeden 
Fall eine höchst interessante Thematik.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Norbert schrieb:
> Ich spiele mit dem Gedanken, einen Barrel- oder Funnel-Shifter mit
> entsprechender Bitbreite in VHDL zu konstruieren (aufwendig aber
> effizient) und dafür diesen ganzen Komponentenkram rauszuwerfen. Leider

The 18x18 Multiplizierer kannst Du auch als Barrelshifter verwenden.

von Christian R. (supachris)


Lesenswert?

ehemaliger Spartanentwickler schrieb:
> Ich habe einen Spartan 6 mit über 200MHz Grundfrequenz laufen lassen und
> der war auch voll.

Da muss man aber sicherlich viel optimieren um da hinzukommen, oder? Ich 
bin dann irgendwie immer an die Grenzen der Clocking Ressourcen 
gestoßen, irgendwie macht das mit dem S6 keinen richtigen Spaß.

von Fpgakuechle K. (Gast)


Lesenswert?

Norbert schrieb:
> Schlumpf schrieb:

> Ich spiele mit dem Gedanken, einen Barrel- oder Funnel-Shifter mit
> entsprechender Bitbreite in VHDL zu konstruieren (aufwendig aber
> effizient) und dafür diesen ganzen Komponentenkram rauszuwerfen. Leider
> habe ich selbst keinerlei Erfahrung auf dem Gebiet und kann nur
> Vermutungen darüber anstellen, wie man sowas am besten realisiert und
> was wirklich Geschwindigkeit in die Logik bringt.

Barrel-shifter ist ne Fingerübung, Xilinx hat trotzdem ne AP drüber 
geschrieben:
http://www.xilinx.com/support/documentation/application_notes/xapp195.pdf

Eventuell ist dergleichen auch beim CoreGenerator zu finden, aber
dergleichen sollte ein Synthesetool problemlos aus VHDL extrahieren und 
selbst auf LUT;DSP-Slice;MULT; etc mappen können.

MfG,

von Schlumpf (Gast)


Lesenswert?

Norbert schrieb:
> Was mir persönlich an dem VHDL Code nicht so gut gefällt, ist der
> Umstand, dass hier die ganzen verschiedenen Bitschiebereien und
> -rotierereien der SHA Berechnung jeweils als einzelne Komponenten mit
> jeweiligen Bitmappings zwischen den Vektoren ausgeführt sind.

Das finde ich auch nicht schön. Es macht das Ganze unleserlich.

> Ich vermute nämlich, dass hier die Wurzeln des Übels liegen, das
> eine höhere Taktfrequenz verhindert.

Die Trennung in mehrere Components wird vermutlich nicht das Probelm 
sein, da die Synthese das eh alles plattklopft. Aber die Tiefe der Logik 
zwischen zwei Registern ist das Problem. Und die wird auch nicht 
geringer, wenn du statt der zig Components alles in eine Component 
packst.

von Ralle (Gast)


Lesenswert?

Schlumpf schrieb:
> Die Trennung in mehrere Components wird vermutlich nicht das Probelm
> sein, da die Synthese das eh alles plattklopft.
Nur, wenn man das auch ausdrücklich anweist! "Maintain Hierarchie" 
heisst das oder "Optimization Cross Hierarchie"

von Schlumpf (Gast)


Lesenswert?

Ralle schrieb:
> Schlumpf schrieb:
>> Die Trennung in mehrere Components wird vermutlich nicht das Probelm
>> sein, da die Synthese das eh alles plattklopft.
> Nur, wenn man das auch ausdrücklich anweist! "Maintain Hierarchie"
> heisst das oder "Optimization Cross Hierarchie"

Nur teilweise richtig.

Die Logiktiefe der beschriebenen Logik bleibt die gleiche (Anzahl der 
LUTs in diesem Pfad).
Eventuell könnte das Routing ein wenig anders ausfallen, aber die 
Logiktiefe zwischen zwei Registern wird nicht kleiner oder größer, wenn 
diese auf mehrere Components aufgeteilt ist.

von Fpgakuechle K. (Gast)


Lesenswert?

Schlumpf schrieb:
> Ralle schrieb:
>> Schlumpf schrieb:
>>> Die Trennung in mehrere Components wird vermutlich nicht das Probelm
>>> sein, da die Synthese das eh alles plattklopft.
>> Nur, wenn man das auch ausdrücklich anweist! "Maintain Hierarchie"
>> heisst das oder "Optimization Cross Hierarchie"
>
> Nur teilweise richtig.
>
> Die Logiktiefe der beschriebenen Logik bleibt die gleiche (Anzahl der
> LUTs in diesem Pfad).
> Eventuell könnte das Routing ein wenig anders ausfallen, aber die
> Logiktiefe zwischen zwei Registern wird nicht kleiner oder größer, wenn
> diese auf mehrere Components aufgeteilt ist.

Hab ich mal anders gelernt.

Lieg bspw. ein NEG am Ausgang der einen und einer am Eingang der anderen 
Komponente werden diese bei Optimierung über Grenzen wegoptimiert. Also 
es kann sich schon die Logiktiefe (LUT-merge) ändern. Das Routing 
dagegen sollte bei nicht optimierbaren mapping unverändert bleiben.

MfG,

von Schlumpf (Gast)


Lesenswert?

Fpga Kuechle schrieb:
> Hab ich mal anders gelernt.
>
> Lieg bspw. ein NEG am Ausgang der einen und einer am Eingang der anderen
> Komponente werden diese bei Optimierung über Grenzen wegoptimiert. Also
> es kann sich schon die Logiktiefe (LUT-merge) ändern. Das Routing
> dagegen sollte bei nicht optimierbaren mapping unverändert bleiben.
>
> MfG,

Genau das meine ich ja auch.. zwei NEG in einem Datenpfad werden 
wegoptimiert, egal, ob sie in zwei getrennten Components stehen, oder in 
einer.
Vielleicht habe ich mich da ein wenig missverständlich ausgedrückt.

von Ralle (Gast)


Lesenswert?

Schlumpf schrieb:
> zwei NEG in einem Datenpfad werden
> wegoptimiert, egal, ob sie in zwei getrennten Components stehen
Das würde aber bedeuten, dass sich an der Komponente das Signal dreht. 
Was ist dann mit ChipsScope? Was mit einer Post-Route-Simu? Das Signal 
muss ja dann verschwinden.

von Norbert (Gast)


Lesenswert?

Uwe Bonnes schrieb:
> The 18x18 Multiplizierer kannst Du auch als Barrelshifter verwenden.

Fpga Kuechle schrieb:
> Barrel-shifter ist ne Fingerübung, Xilinx hat trotzdem ne AP drüber
> geschrieben:
> http://www.xilinx.com/support/documentation/application_notes/xapp195.pdf

Super, danke für die netten Hinweise! Das ist ja mal eine nützliche 
Sache. Multiplizierer sind genug vorhanden für die erforderliche 
Bitbreite. Das ist dann zwar nicht mehr portabel aber egal. Der Zweck 
(oder der FPGA) heiligt die Mittel ;-)

von Norbert (Gast)


Lesenswert?

Fpga Kuechle schrieb:
> Eventuell ist dergleichen auch beim CoreGenerator zu finden, aber
> dergleichen sollte ein Synthesetool problemlos aus VHDL extrahieren und
> selbst auf LUT;DSP-Slice;MULT; etc mappen können.

Da gibts in den Templates einen MULT_MACRO. Damit kann man diese 18 Bit 
Multiplikatoren direkt ansprechen und instantiieren.

Beim Core Generator Wizard hab ich auf Anhieb nichts Brauchbares 
gefunden.

von Georg A. (georga)


Lesenswert?

> Das registerretiming habe ich erst kürzlich wieder
> getestet:Obwohl ich eine riesen Bank an FFs hintergehängt
> hatte, hat das balancieren nichts gebraucht.

Das Register-Retiming geht ja prinzipiell vorwärts und rückwärts. 
Irgendwo stand mal, dass xst eine Variante besser kann als die andere. 
Ist jetzt aber auch schon ein paar Jährchen her...

von Omega (Gast)


Lesenswert?

Ich habe mal ein Design mit 156.25 MHz im Spartan-6 gemacht und habe 
hier nicht optimal meine Hardware beschrieben und nie Probleme gehabt. 
Also wenn es bei 100 MHz  Schwierigkeiten macht, dann ist das definitiv 
"Quality of Implementation". Man lernt eben mit den Jahren dazu, wie man 
sein Design vernünftig beschreibt, was machen machen darf, und wo es mal 
Schwierigkeiten geben kann.

Es sollte einem beim Beschreiben schon bewusst sein, wie die Logik 
grundsätzlich dazu aussieht. Ein FPGA ist nun eben mal kein Prozessor! 
Aber viel zu oft wird das übersehen!

Ich freue mich schon auf die ganzen Threads, wenn mal das HLS von Xilinx 
unter den Leuten ist. C-Programmieren auf Hardware-Basis - Viel Spaß!

von Norbert (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> Das Design mit FFs zu entspannen, ist natuerlich ein Mittel der Wahl
> fuer ein ein synchrones Design.

Diese Möglichkeit wurde mehrfach in diesem Thread erwähnt. Das scheint 
jedoch mehr eine Erfahrungssache aus der Praxis zu sein, die ich bis 
jetzt nicht in der Literatur gefunden habe.

Gibts im Internet irgendwelche Ressourcen, wo ich mich über dieses 
Verfahren informieren kann?

von Mac G. (macgyver0815)


Lesenswert?

Ich schrob ja schon ganz oben: Pipeline

von Christian R. (supachris)


Lesenswert?

Naja, nicht immer lässt sich die Logik so pipelinen, dass nur eine 
Logikstufe zwischen den FlipFlops ist, und dann geht die maximale 
Geschwindigkeit schnell runter. Der Spartan 6 hat zum Glück schon LUTs 
mit 6 Eingängen, aber auch das hilft manchmal nicht. Wie ich oben 
schrieb, ein Design von mir (S6-100) hat auch ca. 60% Füllgrad aber die 
Block RAMs alle benutzt, schafft reichlich 100MHz, weil einige Teile 2 
bis 3 Logikstufen zwischen 2 FF haben müssen. Und gerade wenn man alle 
Block RAMs braucht, ist das Routing quer über den Chip auch eine gute 
Bremse.

von Norbert (Gast)


Lesenswert?

Mac Gyver schrieb:
> Ich glaube Du musst da noch ein paar Details zu Deinem konkreten Design
> posten...
> Also z.B. hast Du da nur eine riesen kombinatorische Logik oder haste es
> gut gepipelined?

Also ich hab vor allem mal zwei Dinge, das eine ist so gut wie keine 
Ahnung und das zweite ist die große Hoffnung, hier in dem Forum noch 
etwas lernen zu können. Ich kann daher nur nochmal meine Frage von 
meinem Posting vom 14.07.2013, 21:42 Uhr wiederholen.

Gibts dazu Informationen und wenn ja, wo finde ich diese?

Vielen Dank schon mal für entsprechende Hinweise!

von Schlumpf (Gast)


Lesenswert?

Ralle schrieb:
> Was ist dann mit ChipsScope? .....

Wenn du einen "Logic Analyzer" in dein Design dazupackst und einen Scope 
auf ein Signal legst, dann wird dieses Signal natürlich nicht 
wegoptimiert.
Es besteht ja dann eine logische Verknüpfung mit diesem Signal und das 
macht die Synthese natürlich nicht weg.
Darum ist ein Design MIT Chipscope auch ein anderes, als ohne ChipScope

@ Norbert:

Was mit Pipelinig gemeint ist, ist vielleicht an einem einfachen 
Beispiel erklärt.
A,B und C seien Registerausgänge
X sei ein Registereingang

X = f(A,B,C)
Wenn die Funktion eine gewisse Komplexität erreicht hat, dann wird der 
Pfad durch die Logik eventuell so groß (lang), dass die Laufzeit der 
Signale durch die Logik so langsam ist, dass das Ergebnis nicht mit dem 
nächsten Systemtakt am Eingang X stabil vorliegt.

Das kann dann durch Pipelining entspannt werden, indem ein zusätzliches 
Register (Y) eingefügt wird.

Dann ergibt sich z.B. folgendes:
Y = f(A,B)
X = f(Y,C)

Somit ist die Logiktiefe zwischen den Registern geringer und damit die 
Signallaufzeit kürzer. Allerdings dauert es zwei Takte, bis das Ergebnis 
in X vorliegt.

von Norbert (Gast)


Lesenswert?

Schlumpf schrieb:
> Was mit Pipelinig gemeint ist, ist vielleicht an einem einfachen
> Beispiel erklärt.
>...
> Somit ist die Logiktiefe zwischen den Registern geringer und damit die
> Signallaufzeit kürzer. Allerdings dauert es zwei Takte, bis das Ergebnis
> in X vorliegt.

Ok, das leuchtet mir ein. Vielen Dank für die Erklärung. Wie geht man 
sowas in der Praxis an? Dazu braucht man sicherlich einiges an Erfahrung 
um ein Gefühl dafür zu entwickeln, wo es hängen könnte und wie man die 
Lösung erarbeitet.

von Gamma (Gast)


Lesenswert?

Omega schrieb:
> wenn mal das HLS von Xilinx
> unter den Leuten ist
Die meisten proggen doch jetzt schon wie in C - ist nur logisch sowas 
nazubieten :D

Xilinx rüstet ja offenbar die gesamte chain auf Prozessorzugiffe um, sie 
AX-Interface.

Norbert schrieb:
> die ich bis
> jetzt nicht in der Literatur gefunden habe.
Was will man da auch gross beschreiben?
Dass mehr FFs zu weniger Kombinatorik zwischen Denselben führen? Das ist 
ja augenscheinlich so.

Christian R. schrieb:
> Naja, nicht immer lässt sich die Logik so pipelinen, dass nur eine
> Logikstufe zwischen den FlipFlops ist,
Nach der Aussage von Theoretikern ist genau das möglich. Alle Funktionen 
werden auf LUTs abgebildet und die stecken in slices, die ein FF 
enthalten. Man muss nur genug FFs investieren.

von Schlumpf (Gast)


Lesenswert?

@ Norbert:

Ja, dazu bedarf es ein wenig Erfahrung um abschätzen zu können, wo es 
"eng" werden könnte.

Die Reports von Synthese und PaR können einem dabei helfen, jedoch muss 
nicht zwingend der von den Tools als krischer Pfad identifizierte der 
tatsächliche Übeltäter sein.
Es passiert auch oft, dass die Toolchain mit Hngen und Würgen einen 
kritischen Pfad noch reingepresst bekommt, ihr dann aber für einen 
weniger kritischen Pfad die Puste ausgeht und sie dann genau diesen als 
kritisch reported.

Letztendlich hilft es dir, in Hardware zu denken und zu überlegen, was 
du mit deinen VHDL-Konstrukten tatsächlich als Hardware beschreibst.
Stell dir vor, was dabei entsteht und überlege dann, ob das in diskreter 
Logik aufgebaut groß oder eher klein wäre. So findest du am ehesten die 
wirklich kritischen Pfade.

Genau aus diesem Grund stehen mir auch immer die Haare zu Berge, wenn 
die Leute von VHDL "programmieren" reden. Es ist eben kein 
"programmieren" im klassichen Sinne, sondern ein "Beschreiben". Man darf 
nie die Hardwaresicht aus den Augen verlieren, sonst ist man sehr 
schnell aufgeschmissen, wenn es darum geht, ein Design auf 
Geschwindigkeit oder Platzbedarf zu optimieren (ist jedenfalls meine 
Meinung)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.