Wie am besten in die Konsole Zeichen ausgeben?

Für Fragen von Einsteigern und Programmieranfängern...
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

Interessanterweise wird die Zeiger Methode aber erst so ab 10 000 Zeilen schneller als MemW.

Dies ist wirklich komisch ! :shock:

Vielleicht optimiert die CPU noch etwas, es könnte sein, das dies auf einem original 8088er ganz anders aussieht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von marcov »

Mathias hat geschrieben:Ich weis zwar nicht, was du mit FAR data model meinst,
Aber wen ich es jetzt mit

Code: Alles auswählen

c:\FPC\3.0.0\bin\i386-win32\ppcross8086.exe -WmLarge PACMAN.lpr

kompiliere, funktioniert es fehlerfrei.


FAR sind "grosse" Pointer (seg+ofs), dem Gegensatz ist NEAR (typisch nur ofs, seg ist implizit, entweder global oder per unit)

Die unterschiedliche -Wm memory models unterscheiden sich ob code und data near oder FAR sein.

Da neben gibst auch noch HUGE, (welches es nicht gibt in TP, aber bestand in TC++), was ein FAR ist die ständig normalisiert wird. Im Huge modus kann damit also Zeiger laufen lassen über blocken großer dann 64kb. hat aber die staendige Normalisierung als overhead.

Siehe zb http://wiki.freepascal.org/DOS#New_pointer_types

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

FAR sind "grosse" Pointer (seg+ofs), dem Gegensatz ist NEAR (typisch nur ofs, seg ist implizit, entweder global oder per unit)

Wen ich das richtig verstehe, ist für kleine schnell Sachen das NEAR-Modell besser, das man nicht mit Seg hantieren muss ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Nixsager »

Jole hat geschrieben:Interessanterweise wird die Zeiger Methode aber erst so ab 10 000 Zeilen schneller als MemW.

Die Aussage über die Put-Methode wollte ich korrigieren. Denn bei einer Routine ist sie langsamer als die Mem-Method und bei einer anderen schneller.
Mir ist das zu hoch.

Ich erweitere gerade das Testprogramm von Mathias wo der String mit mehreren Methoden ausgegeben wird, und wo der ganze Bildschirm beschrieben wird.
Wenn es soweit ist, laden ich den Quelltext hoch. Ich hoffe ihr testet es mal.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von marcov »

Mathias hat geschrieben:
FAR sind "grosse" Pointer (seg+ofs), dem Gegensatz ist NEAR (typisch nur ofs, seg ist implizit, entweder global oder per unit)

Wen ich das richtig verstehe, ist für kleine schnell Sachen das NEAR-Modell besser, das man nicht mit Seg hantieren muss ?


Ja (auf alten Eisen), UND gleich. Also Code NEAR, data NEAR, aber auch CODE=DATA, also Code model Tiny.

Vordefinierte Konstanten können dann, wie im 32-bit Modus durchgegeben werden ohne kopieren oder laden von Segmenten.

Das Problem ist das TIny in 16-bit eine Begrenzung auf 16-bit, also 64kb für ALLES heißt (code,stack,data), was recht unpraktisch ist.

Im 32-bit Modus ist das auch so, aber mit 4GB als Grenze nicht so unbequem. Für reine Schnellheit >386 ist 32-bit Modus am besten.

Ich glaube der 386, weil schon 32-bit, ist schneller mit 16-bit, bin mir aber nicht ganz sicher.

Jole
Beiträge: 114
Registriert: Fr 4. Jul 2014, 14:39
OS, Lazarus, FPC: Linux
CPU-Target: amd64

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Jole »

Mathias hat geschrieben:
Interessanterweise wird die Zeiger Methode aber erst so ab 10 000 Zeilen schneller als MemW.

Dies ist wirklich komisch ! :shock:

Da hab ich mich wohl etwas unglücklich ausgedrückt, ich wollte eigentlich sagen das es erst da Optisch spürbar wird.
Jetzt kann ja aber ein Textmodus 25/43 oder 50 (je nach Karte) und da sind keinerlei Zeiten Messbar geschweige denn lässt sich da Optisch erkennen wer da schneller ist. Auf einem 8086iger werden die Zeiten natürlich andere sein, dass muss Nixsager aber selber Testen.

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Nixsager »

Jole hat geschrieben:@Nixsager: Wenn die MemW Methode schneller ist und du die Funktionsweise auch besser verstehst, würde ich diese Methode auch nutzen.

Mir ist es schon wichtig das ich den Code verstehe.
Ich will ja auch meinen Code auch optimieren.

Deine Put-Methode scheint für positionierte Textausgaben am schnellsten zu sein.
Ich vermute mal, das die Methode vorher langsam war lag daran, das die Daten nicht im gleichen Format wie bei der Vergleichsfunktion vorlagen.

Um den ganz Textbildschirm schnell zu zeichenen ist die MOVS-Methode unschlagbar.
Aber bei dieser Methode müssen die Daten schon im richtigen Format vorliegen.
Will man nur einen Text damit ausgeben, ist diese Method am langsamsten, da die Daten vor dem ausgeben angepasst werden müssen.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Jole
Beiträge: 114
Registriert: Fr 4. Jul 2014, 14:39
OS, Lazarus, FPC: Linux
CPU-Target: amd64

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Jole »

Will man nur einen Text damit ausgeben, ist diese Method am langsamsten, da die Daten vor dem ausgeben angepasst werden müssen.

Genau deshalb ist die Methode eben nicht unschlagbar :wink:
Wie ich oben schon erwähnt habe, würde ich das nutzen was ich ab besten verstehe. Mem$ sollte selbst mit einem 4.77 Bar getriebenen Dapfantrieb gute ergebnisse bringen! Bei der Entwicklung würde ich mich auch nicht all zu sehr auf die Geschwindigkeit Konzentrieren sondern erst mal die Funktionalität erarbeitenl, verbessern kann man hinterher immer noch.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

Im 32-bit Modus ist das auch so, aber mit 4GB als Grenze nicht so unbequem. Für reine Schnellheit >386 ist 32-bit Modus am besten.
Ich glaube der 386, weil schon 32-bit, ist schneller mit 16-bit, bin mir aber nicht ganz sicher.

Gewisse 32Bit-Befehle und Register funktionierten auch im Real-Modus.
Der 386er war schon schneller, abgesehen von der Taktrate. Nur der 386SX, war zum Teil langsamer als ein 286er, da dieser auch 32Bit-Daten durch den 16Bit Bus zwängen musste.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Nixsager »

Michl hat mir ja für mein Ditherung-Problem ein Lösung gegeben, und da kam ein Frage auf.

In der Konsole kann man ja nicht genauso vorgehen wie unter DOS, wo man den Videospeicher beschreibt.
Aber das Ergebnis von Write ist ja unter der Konsole und unter DOS das selbe.

Wie geht man bei einem Konsolen Programm denn vor?
Ich glaube nicht, das Write in der Konsole die beste Möglichkeit ist.
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

Unter Win kann man auch jedes Zeichen ansprechen, aehnlich wie im Vram.
Ich kann es dir mal rausuchen, wen ich wieder vorm PC hocke.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von fpGUIcoder »

Mathias hat geschrieben:Das waren schon noch Zeiten, wo man alle aus der Kiste raus holte. Da könnte M$ noch einiges abgucken mit seinem aufgeblähten Windows. :wink:


Nun ja, Linux wird auch von Version zu Version hardwarehungriger.

Damals musste man auch alles aus der Kiste rausholen. Wäre aber gut wenn das heute auch der Fall wäre. Jede heutige Programmversion wird automatisch harwaregieriger, obwohl gar nicht soooo viele neue sinnvolle Funktionen in der neuen Version drin sind. Beim Übergang z.B. von Wordstar zu MS Word war das noch grundlegend anders, da lohnte es sich noch, die neue Version zu installieren und dafür besser Hardware zu kaufen:

-Wordstar:
Unmengen Papier verdruckt, keine Vorschaufunktion

-MS Word
Vorschaufunktion hat Seitenansicht vor dem Drucken ermöglicht
Neue Textformatierungsfunktionen und Standardvorlagen + Rechtschreibkontrolle

Das nenne ich echten Mehrwert gegenüber der älteren Version.


Aber was kann der neue Flashplayer gegenüber dem alten aber kleineren weniger ressourcenintensiven besser als der alte?

Was kann der brandneue aber aufgeblähte Firefox gegenüber dem alten aber weniger ressoucenhungrigen besser?????

Ich glaube hier nicht an höhere Sicherheit.

Und ich bin es leid, an einem Wettrüsten teilzunehmen um den schnellsten Rechner mit den aktuellsten Sicherheitsupdates, die nur mein System immer träger machen, aber KEINEN Gewinn an zusätzlicher wirklicher Sicherheit und Anonymität bringen. Die wirklich absolute Sicherheit gibt es nicht.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

Und wen man nicht Interpreter verwenden wuerde, so wie es Java ist, wuerde auch alles viel effizienter sein.
Native Anwendungen laufen um einiges besser. :idea:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie am besten in die Konsole Zeichen ausgeben?

Beitrag von Mathias »

Mathias hat geschrieben:Unter Win kann man auch jedes Zeichen ansprechen, aehnlich wie im Vram.
Ich kann es dir mal rausuchen, wen ich wieder vorm PC hocke.


Ich habe den Code gefunden, das CLS müssten noch das Zeichen und Attribut angepasst werden.

Code: Alles auswählen

  procedure OutCharXY(x, y: integer; ch: char; col: byte);
  var
    numChars: integer = 1;
    c: coord;
    p: longword = 0;
  begin
    c.X := x;
    c.Y := y;
    FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col, numChars, c, p);
    FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ch, numChars, c, p);
  end
 
  procedure Cls;
  var
    numChars: integer = 80 * 25;
    c: coord;
    x: longword = 0;
  begin
    c.X := 0;
    c.Y := 0;
    FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), $13,
      numChars, c, x);
    FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), char(13),
      numChars, c, x);
  end;   


Noch ein Code mit einem Buffer.

Code: Alles auswählen

program project1;
uses
  Windows,
  Classes;
var
  x, y: integer;
  wHnd, rHnd: HANDLE;
const
  Width = 80;
  Height = 25;
  bufferSize: COORD = (x: Width; y: Height);
  characterBufferSize: COORD = (x: Width; y: Height);
  characterPosition: COORD = (x: 0; y: 0);
  consoleWriteArea: SMALL_RECT = (Left: 0; Top: 0; Right: Width - 1; Bottom: Height - 1);
var
  consoleBuffer: array[0..Width * 2 * Height] of CHAR_INFO;
  a: byte;
 
  r: small_Rect;
begin
  wHnd := GetStdHandle(STD_OUTPUT_HANDLE);
  rHnd := GetStdHandle(STD_INPUT_HANDLE);
 
  SetConsoleTitle('Mien Konsolen Programm');
 
  r.Left := 0;
  r.Top := 0;
  r.Bottom := 54;
  r.Right := 79;
  SetConsoleWindowInfo(wHnd, True, r);
 
  SetConsoleScreenBufferSize(wHnd, bufferSize);
 
  for y := 0 to Height - 1 do begin
    for x := 0 to Width - 1 do begin
      consoleBuffer[x + (Width + 20) * y].AsciiChar := char(x);
      a := y;
      a := a or $f0;
      consoleBuffer[x + (Width + 20) * y].Attributes := a;
    end;
  end;
  characterBufferSize.X := Width + 20;
  //  characterBufferSize.Y:=5;
  //  characterPosition.X:=32;
  //  characterPosition.Y:=4;
  consoleWriteArea.Left := 1;
  consoleWriteArea.Top := 1;
  consoleWriteArea.Right := 60;
  consoleWriteArea.Bottom := 40;
 
  WriteConsoleOutputA(wHnd, @consoleBuffer, characterBufferSize, characterPosition, consoleWriteArea);
 
  readln;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten