ja niedawno zadał to pytanie:Jak utworzyć tablicę uint8_t, która nie podważa ścisłego aliasingu?
Using this pointer causes strange deoptimization in hot loop
Problem polegał na tym, że pisałem do tablicy typu uint8_t
i kompilator traktuje go tak, jakby to mogło alias ze wskaźnikiem sposobu this
(typu struct T*
), ponieważ void*
i char*
(= uint8_t*
) zawsze mogą aliasować dowolny inny wskaźnik w C++. Takie zachowanie spowodowało brak możliwości optymalizacji. Oczywiście chcę tego uniknąć. Pytanie brzmi: czy mogę zadeklarować tablicę uint8_t
, która wymusza ścisłe aliasingowanie, tj. Czy kompilator traktuje jak nigdy aliasing za pomocą dowolnego wskaźnika innego typu? Oznacza to, że szukam czegoś podobnego do typu , który jest uint8_t
ze specjalnym zachowaniem aliasingu. Czy istnieje sposób, aby to osiągnąć?
Przykładowy kod pokazujący, co mam na myśli, pożyczony od innego pytania i uproszczony. Aby uzyskać więcej informacji, zapoznaj się z umieszczonego pytanie i jej akceptowany odpowiedź:
struct T{
uint8_t* target;
void unpack3bit(char* source, int size) {
while(size > 0){
uint64_t t = *reinterpret_cast<uint64_t*>(source);
/** `this->target` cannot be cached in a register here but has
to be reloaded 16 times because the compiler
thinks that `this->target` could alias with `this` itself.
What I want is a special uint8_t type that does not trigger
this behaviour. */
this->target[0] = t & 0x7;
this->target[1] = (t >> 3) & 0x7;
this->target[2] = (t >> 6) & 0x7;
this->target[3] = (t >> 9) & 0x7;
this->target[4] = (t >> 12) & 0x7;
this->target[5] = (t >> 15) & 0x7;
this->target[6] = (t >> 18) & 0x7;
this->target[7] = (t >> 21) & 0x7;
this->target[8] = (t >> 24) & 0x7;
this->target[9] = (t >> 27) & 0x7;
this->target[10] = (t >> 30) & 0x7;
this->target[11] = (t >> 33) & 0x7;
this->target[12] = (t >> 36) & 0x7;
this->target[13] = (t >> 39) & 0x7;
this->target[14] = (t >> 42) & 0x7;
this->target[15] = (t >> 45) & 0x7;
source+=6;
size-=6;
target+=16;
}
}
};
Czy na pewno chcesz to zrobić 'target + = 16'? Wtedy stracisz pierwotny wskaźnik T :: cel. –
Muszę przyznać, że nie rozumiem, co sprawia, że aliasing z 'this' (zamiast jakiejkolwiek innej zmiennej) jest wyjątkowy. Nie jestem również pewien, czy jest to istotne. Zdecydowanie interesujące pytanie i tak. –
@Joachim Pileborg: Tak, wszystko w porządku. Pomyśl o 'celu' jako o" aktualnej głowicy zapisu ". Początek bufora 'target' jest przechowywany gdzie indziej. Poza tym ten kod służy tylko do pokazania problemu :). – gexicide