2017-03-23 4 views
1

Ich frage mich, ob es möglich ist, auf gcc zu deuten, dass ein Zeiger auf eine ausgerichtete Grenze zeigt. wenn ich eine Funktion haben:c Ausrichtung von Zeigern

void foo (void * pBuf) { 
    uint64_t *pAligned = pBuf; 
    pAligned = ((pBuf + 7) & ~0x7); 
    var = *pAligned; // I want this to be aligned 64 bit access 
} 

Und ich weiß, dass pBuf 64 Bit ausgerichtet ist, ist es eine Möglichkeit, gcc zu sagen, dass pAlignedPunkte auf eine 64-Bit-Grenze? Wenn ich das tue:

uint64_t *pAligned __attribute__((aligned(16))); 

Ich glaube, das bedeutet, dass die Adresse des Zeigers 64 Bit ausgerichtet ist, aber es nicht den Compiler sagen, dass das, was er zeigt, ausgerichtet ist, und daher würde der Compiler wahrscheinlich sagen es um hier einen unkoordinierten Abruf zu machen. Dies könnte die Dinge verlangsamen, wenn ich ein großes Array durchlaufe.

Antwort

2

Es gibt mehrere Möglichkeiten, GCC über die Ausrichtung zu informieren.

Zum einen können Sie Attribut ausrichten heften sich an pointee, anstatt Zeiger:

int foo() { 
    int __attribute__((aligned(16))) *p; 
    return (unsigned long long)p & 3; 
} 

Oder können Sie (relativ neu) builtin verwenden:

int bar(int *p) { 
    int *pa = __builtin_assume_aligned(p, 16); 
    return (unsigned long long)pa & 3; 
} 

Beide Varianten return 0 optimieren aufgrund Ausrichtung.

Leider ist die folgende scheint nicht zu funktionieren:

typedef int __attribute__((aligned(16))) *aligned_ptr; 

int baz(aligned_ptr p) { 
    return (unsigned long long)p & 3; 
} 

und dieses weder

typedef int aligned_int __attribute__((aligned (16))); 

int braz(aligned_int *p) { 
    return (unsigned long long)p & 3; 
} 

obwohl docs suggest the opposite.

+0

Jetzt, wo Sie es erwähnen, das erste Beispiel klingt so offensichtlich ... Nicht sicher, wie ich das verpasst habe. Vielen Dank. Ich bin überrascht, dass das Typedef nicht funktioniert. Es könnte in anderen Teilen meines Codes nützlich gewesen sein. – blackghost

+0

@John Richtig, GCC sogar [behauptet, es zu unterstützen] (https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#Common-Type-Attributes) in der Dokumentation, aber ich konnte nicht bekommen es funktioniert mit meinem GCC 5.4. – yugr

+0

Ich nehme an, dass Sie in den letzten zwei Fällen versuchen, einen Parameter auszurichten, und der Parameter ist zur Kompilierzeit nicht bekannt, daher hätte gcc keine Möglichkeit, den Parameter auszurichten. Es könnte in der Lage sein, eine Warnung zu erzeugen, wenn Sie versucht haben, einen Parameter zu übergeben, der nicht ausgerichtet wurde, aber wenn jemand 0xabcd0001 auf den Stapel geschoben hat, wäre der Zeiger tatsächlich ungerade. Der Code im Inneren macht jedoch wahrscheinlich die Annahme der Ausrichtung, und Speicherzugriff würde wahrscheinlich eine nicht ausgerichtete Ausnahme verursachen ... – blackghost