Inlineassembler für ARV-GCC: Habe Schwierigkeiten mit den "Constraint Modifiers"

Gast #3225404
Hallo zusammen,

ich habe folgendes Problem:
ich möchte jedes 2. Bit aus einem 16-Bit-integer (unsigned) in einen 
8-Bit-integer (unsigned) schreiben. Da dies sehr sehr häufig gemacht 
werden muss habe ich mir ein paar Gedanken gemacht wie man hier etwas 
"tunen" könnte.

Mein bisheriger Code erledigt das recht zuverlässig, nur leider recht 
langsam.
1
uint16_t in;
2
uint8_t out;
3
for( uint8_t i=0; i<8; i++ )
4
{
5
  if( in & (1<<14) )
6
    out++;
7
  out<<1;
8
  in<<2;
9
}

Mein vielleicht schnellerer Ansatz sieht folgendermaßen aus:
1
uint16_t in;
2
uint8_t out=0, out2;
3
for( uint8_t i=0; i<4; i++ )
4
{
5
  __asm(  "LSL  %1  \n\t"
6
          "LSL  %1  \n\t"
7
          "ROL  %0  \n\t"
8
          : "+r" (out)
9
          : "+r" (in&0xFF) );
10

11
  __asm(  "LSL  %1  \n\t"
12
          "LSL  %1  \n\t"
13
          "ROL  %0  \n\t"
14
          : "=r" (out2)
15
          : "+r" (in>>8) );
16
  out = out | (out2<<4);
17
}
Und auch wenn ich mir mittlerweile nicht wirklich sicher bin ob der Code 
effizienter ist (ein genauer Vergleich steht noch aus) stelle ich mich 
wirklich doof mit den Constraints und den Constraint Modifiers an.
Ich werde gerade nicht schlau was Output, was Input und was wie wer sein 
muss. Und genau das ist mein Problem, nicht die ursprüngliche Aufgabe, 
sondern mein Unverständnis was was ist und warum ein Register Output ist 
und das andere nicht.
Für meine Begriffe ist ja das "out"-Register sowohl Output als auch 
Input (muss ja zuvor 0x00 sein). "out2" ist nur Output. "in" ist 
eigentlich nur Input, wird aber verändert, also auch muss es auch Output 
sein?

Wäre schön wenn mir jemand da mal ein Lichtlein einschalten könnte. Ich 
glaube ich stehe gerade vollkommen auf dem Schlauch.

Vielen Dank
Drago
Drago schrieb:
> Da dies sehr sehr häufig gemacht
> werden muss

Wie häufig?
Und wie lang ist die Dauer im Verhältnis zum restlichen Code der Task?

Anfänger unterliegen oft dem Irrtum, daß sie meinen, etwas optimieren zu 
müssen, was fast keinen Einfluß auf die Gesamtperformance hat.


Assembler ist nichts, was man ohne Notwendigkeit im Code haben möchte.
Es macht den Code schlechter lesbar, wartbar und unportabel, falls man 
den MC oder Compiler wechseln möchte.
Gast
Ich hab mit meinem Oszi und einem Debug-Pin mal gemessen wie lange er wo 
braucht und für die Konvertierung des Manchester-Codes zu nutzbaren 
Daten (genau das ist das hier) benötigt der µC 40% der Zeit. weitere 50% 
gehen für alle möglichen anderen Aufgaben drauf. 10% sind noch frei.
Das spielt aber nicht ganz die große Rolle, mich ärgert mehr, dass ich 
das gerade nicht kapier welcher Contraint Modifier wann genommen werden 
muss und wann ein Register also output oder input zählt.
Drago schrieb:
> Ich werde gerade nicht schlau was Output, was Input und was wie wer sein
> muss.
[... Ich auch nicht, aber das ist nicht der Maßstab. :) ]

Dein Assemblerschnipsel schiebt 4x was hin- und her. Dein C-Code schiebt 
8x was anderes und vergleicht und rechnet noch. Das soll dasselbe 
Ergebnis bringen?
Drago schrieb:
> Und auch wenn ich mir mittlerweile nicht wirklich sicher bin ob der Code
> effizienter ist

Deutlich effizienter, als das ganze Geschiebe in einer Schleife, sind 
jedenfalls 8 BST/BLD-Pärchen. Und es befreit dich auch gleich von einem 
großen Teil deiner Kopfschmerzen:
> Für meine Begriffe ist ja das "out"-Register sowohl Output als auch
> Input (muss ja zuvor 0x00 sein). "out2" ist nur Output. "in" ist
> eigentlich nur Input, wird aber verändert, also auch muss es auch Output
> sein?
Man hat dann nur ein "out", das eindeutig nur Output ist, und "in" wird 
nicht verändert, ist also eindeutig nur Input.
Persönliche Seite
Da es bereits Probleme mit der Formulierung einer C-Lösung gibt, würde 
ich hier von Inline-Assembler abraten.  Mit
1
#include <stdint.h>
2

3
uint8_t func (uint16_t in)
4
{
5
    uint8_t out = in & (1 << 0);
6
    
7
    if (in & (1 <<  2))  out |= 1 << 1;
8
    if (in & (1 <<  4))  out |= 1 << 2;
9
    if (in & (1 <<  6))  out |= 1 << 3;
10
    if (in & (1 <<  8))  out |= 1 << 4;
11
    if (in & (1 << 10))  out |= 1 << 5;
12
    if (in & (1 << 12))  out |= 1 << 6;
13
    if (in & (1 << 14))  out |= 1 << 7;
14
    
15
    return out;
16
}
erhältst du eine Lösung, die nichts hinter Assembler zurücksteht.
Gast
Peter Dannegger schrieb:

> Anfänger unterliegen oft dem Irrtum, daß sie meinen, etwas optimieren zu
> müssen, was fast keinen Einfluß auf die Gesamtperformance hat.

Das ist wahr.

> Assembler ist nichts, was man ohne Notwendigkeit im Code haben möchte.
> Es macht den Code schlechter lesbar

Das ist ABSOLUTER SCHWACHSINN. Die unleserlichste aller Sprachen ist und 
bleibt C. Nur C-Junkies, die diesen Scheiß gewohnheitsmäßig nehmen, 
empfinden das anders. Typischer Gewohnheits-Drogeneffekt, bloß ohne 
wirklich angenehme Empfindung, wie er bei richtigen Drogen wenigstens 
gelegentlich rauskommt.

> unportabel

Blah, bläh.

Ja klar, Asm ist tatsächlich praktisch nicht architekturübergreifend 
portabel.

Allerdings ist der allermeiste C-Code, das genausowenig. Und falls doch, 
ist er wiederum kaum noch les- oder wartbar, denn "Portabilität" wird 
überwiegend durch endlose #ifdef-Orgien erreicht.

Denn der harte Kern der vielgelobten Portabilität von C ist: Es gibt sie 
garnicht, jedenfalls nicht als Eigenschaft der Sprache selber, sondern 
nur als Ergebnis der Tatsache, daß sie einen Präprozessor beschäftigt.

Das tun allerdings auch (Macro-)Assembler...

Sprich: Man braucht eigentlich nur Assembler für verschiedene 
Zielsysteme, die einen gemeinsamen Satz an Präprozessor-Anweisungen 
haben, um genauso "portable" Programme wie in C schreiben zu können.

Lustig: Genauso ist C entstanden. Der Dreck ist letztlich nicht mehr als 
ein aufgedonnerter Macroassembler mit völlig kruder Syntax.
Gast
>Mann, mann. Bin ich froh, daß ichnicht mit so nem neutotischen Nörgler
>wie c-hater zusammen arbeiten muß!

Den nimmt doch hier sowieso keiner ernst.
Ist halt der Pausenclown;)
Gast
Wenn man bedenkt, wie direkt PDP11 Assembler C Konstrukte abbilden kann, 
dann fragt man sich, warum die ihr Unix nicht weiter in ASM11 schreiben 
wollten und eine dermaßen unbeliebte Sprache erfinden mußten.
(wer Ironie findet, darf sie behalten!)
Gast
Johann L. schrieb:
> Mann, mann. Bin ich froh, daß ichnicht mit so nem neutotischen
> Nörgler
> wie c-hater zusammen arbeiten muß!

mag sein, jedoch wo er Recht hat, hat er Recht.
Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer 
Makroassembler mit gleicher Syntax nicht auch könnte, mit Ausnahme der 
tollen Optimierung die in einigen Fällen aber auch gerne Murks 
produziert.

Die Sprache C bietet auf Compilerebene ohne Präprozessor semantisch 
nichts weiter als ein paar Fallunterscheidungen, Pseudoschleifen, 
Funktionsgerüste, wilde Datentypen und Argumentkonventionen. Das ist auf 
der einen Seite die Stärke, jedoch hat sich auf der Anderen Seite ein 
Crack-Junkie diese krude, unleserliche Syntax ausgedacht.

C++ wäre eine Chance gewesen damit aufzuräumen, denn die eigentlichen 
Mängel hat man versucht durch eine neue Implementation auszubügeln, aber 
nein man konnte es ja nicht lassen eine Abwärtskompatibilität einzubauen 
und damit dem Crack-Junkie die Möglichkeit geben sich wieder so 
auszutoben, wie er es seit Jahr und Tag gemacht hat.

einfach widerlich
Gast
>mag sein, jedoch wo er Recht hat, hat er Recht.
>Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer
>Makroassembler mit gleicher Syntax nicht auch könnte

Aufgrund deines Posts werden jetzt natürlich
1000ende C Programmierer zu Assembler Programmierern
konvertieren.

Was hat dein Post jetzt gebracht?
Nichts. Er war überflüssig.
Gast
holger schrieb:
>>mag sein, jedoch wo er Recht hat, hat er Recht.
>>Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer
>>Makroassembler mit gleicher Syntax nicht auch könnte
>
> Aufgrund deines Posts werden jetzt natürlich
> 1000ende C Programmierer zu Assembler Programmierern
> konvertieren.
>
> Was hat dein Post jetzt gebracht?
> Nichts. Er war überflüssig.

nun, er hat in einem Forum auf einen Beitrag seine Sichtweise dargelegt. 
Einen "Aufruf an alle C-Programmierer die Sprache zu wechseln" kann ich 
beim Besten Willen nicht erkennen. Das bleibt deiner Phantasie 
geschuldet.

Ich neige ihm zuzustimmen, auch wenn es mein täglich Brot ist. Modula 
halte ich für die bessere Alternative, aber es ist nicht gewollt 
(zumindest bei uns). Man beugt sich dem Markt und den etablierten 
Systemen. Das ist mit Windows vergleichbar: hoher Verbreitungsgrad, 
unzählige Anwendungen, sogutwie Jeder hat es. Deswegen ist Windows noch 
lange nicht der Weisheit letzter Schluss.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.