2012-12-05 20 views
6

Bu tür bir takas uygulamasını kullanmanın en büyük tehditleri nelerdir? İplik güvenliği ve zayıf optimizasyonun yanı sıra. Ne zaman başarısız olur (counterexample)?Hafızaya şablon, xor ve işaretçiler kullanılarak yapılan çok fazla değiş tokuş

template<typename T> 
void swapViaMemory(T& left, T& right) { 
    if(&left == &right) { return ; } 

    unsigned int tSize = sizeof(T); 
    unsigned char* lPtr = reinterpret_cast<unsigned char*>(&left); 
    unsigned char* rPtr = reinterpret_cast<unsigned char*>(&right); 

    for(unsigned int i = 0; i < tSize; ++i) { 
     *(lPtr + i) ^= *(rPtr + i); 
     *(rPtr + i) ^= *(lPtr + i); 
     *(lPtr + i) ^= *(rPtr + i); 
    } 
} 
dilbilgisi hatalar için yazık

, ve yanlış (=

cevap

4

T, bu başarısız olacak üyelerinin başka bir işaretçi veya referans bir üye ihtiva eder (niyet varsayılarak her zaman noktası/atıfta işaretçi/başvuru elemanı için olan o örneğe ait veri üyesi).

struct foo 
{ 
    foo() : i(), ref_i(i), ptr_i(&i) {} 
    int i; 
    int& ref_i; 
    int *ptr_i; 
}; 

iki foo amaçları, f1 & f2f2.i ve tersi/noktası sevk edecektir, f1.ref_i ve f1.ptr_i değiştirildikten sonra, swapViaMemory kullanılarak takas söylemek. Ayrıca, referans üye durumunda, bir referansı yeniden yerleştirmek yasadışı olduğu için tanımlanmamış bir davranışı çağırır.

+0

Bu 'başarısızlık' anlamına gelmedikçe işaretçi üyeleri için geçerli değildir. –

+0

@LucDanton Yanıtı – Praetorian

+0

@Praetorian Ohh'a ekledim. İşaretçiler, takas edilen nesnelerin üyeleri arasında çapraz uçacaklar. – shycha

4

Bu niyet taşıma başarısız olur.

kod başlıca amacıdır

.

template<typename T> 
    typename std::enable_if<std::is_pod<T>, void>::type 
    swapViaMemory(T& left, T& right) 
{ 
    using std::swap; 

    swap(left, right); 
} 
+3

Doğru, "niyetiniz" pratikte bir köpek kadar yavaş olmadığında, bu durumda müşterileriniz "niyetiniz" hakkında iki puan vermez. Burada durum böyle değil, genel olarak, kodun ana amacı, * problemleri çözebilmemiz için makine dilini derlemektir. Netlik her zaman için çaba göstermeli, ama aynı zamanda işin iyi ve hızlı bir şekilde yapılmasını sağlamak için daima bir arka koltuk almalıdır. –

+3

@EdS. Bu burada tam olarak böyle değil. “Std :: copy” bile, valuetype POD ise doğrudan doğruya SSE etkin 'memcpy' /' memmov 'haline getirecektir. Profilin var. Ve sonra soruya dönüşür: "Bu hack *** burada *** kullanabilir miyim" değil, "*** bu hack kullanmayın *** değil" – sehe

+0

Anlaştık, bu yüzden benim yorumumu nitelendirdim. * "[Niyet] 'in esas amacı," kesinlikle katılmıyorum. Ben de "yukarıda * bir köpek gibi yavaş * olmak için" yazmayı kastetmiştim. –

0

korkunç olmanın yanı sıra sol ve sağdaki işaret aynı adrese atanırsa başarısız olur.

a^a = 0 
0^a = a 
a^a = 0 
+6

Ne kadar? - eşitlik için hiçbir şey yapmadığına dikkat edin. –

5

Bu tanımsız davranış olmadığını çağırır:(

left == right ise (bu 'hile' için kullanmak budur) ve 'a' Sonra yapacak içeren 1 bayt varlık olduğunu varsayalım a^a = 0 yana T, kolayca kopyalanabilen bir tip değildir.

1

ki için:

struct B{ 
    virtual ~B() {} 
}; 
struct X : B 
{ 
    int x; 
    ~X() { std::cout << x; } 
}; 
struct Y : B 
{ 

}; 

//... 
X x = X(); 
Y y; 
swapViaMemory<B>(x,y);