Özeti
kesmekMerhaba, iki farklı bağımsız 64 bit ikili matrisler A
ve T
(T
kendisinin bir aktarılmamıştır versiyonu matris aktarılmış sürümünü kullanarak çalışmasına çarpma esnasında olanak tanır olduğunu varsayalım T
'ın satırları, ikili aritmetik için süper serin olan sütunlar yerine) ve bu matrisleri çoğaltmak istediğinizde, matris çarpma sonucunun, 64 bit'e kesilmesi ve bazı özel değerlerde 1
değerini daha büyük bir değere getirmenizdir. matris hücresi elde edilen matris hücresi, 1
, aksi takdirde 0
İkili matris çarpım bit twiddling
Örnek
A T
00000001 01111101
01010100 01100101
10010111 00010100
10110000 00011000 <-- This matrix is transposed
11000100 00111110
10000011 10101111
11110101 11000100
10100000 01100010
İkili ve geleneksel çarpma sonuçları:
Binary Traditional
11000100 11000100
11111111 32212121
11111111 32213421
11111111 21112211
11101111 221
11001111 11001311
11111111 54213432
11001111 11001211
Soru
nasıl en verimli konuda yukarıda açıklanan şekilde bu matrisi çarpmak mı?
PS
ben çoğalması için verileri hazırlamak zorunda olduğu durumda, bunun yerine ayrı bit üzerinde çarpma performans ikili and
(yani &
operatör) yararlanmak çalışıyordu: şimdi
ulong u;
u = T & 0xFF;
u = (u << 00) + (u << 08) + (u << 16) + (u << 24)
+ (u << 32) + (u << 40) + (u << 48) + (u << 56);
ikili and
iki yılı Tamsayılardaki A
ve u
gerçekleştirerek aşağıdaki boyun olacaktır:
A u R C
00000001 01111101 00000001 1
01010100 01111101 01010100 3
10010111 01111101 00010101 3
10110000 01111101 00110000 2
11000100 01111101 01000100 2
10000011 01111101 00000001 1
11110101 01111101 01110101 5
10100000 01111101 00100000 1
Yukarıdaki örnekte, R
, A
bitlerinin u
bitt çarpımının sonucunu içerir ve son değeri elde etmek için, bir satırdaki tüm bitleri sum
olmalıdır. Sütun C
'un, yukarıdaki ilk sütunda bulunan değerlere eşit değerler içerdiğine dikkat edin. Yukarıdaki Traditional
matris çarpımı.Sorun şu ki, bu adımda alt-optimal yaklaşım olduğunu düşündüğüm ayrı bir bit üzerinde çalışmam gerektiğidir, http://graphics.stanford.edu/~seander/bithacks.html'u okudum, bunun paralel olarak yapılabileceğine dair bir yol arıyorum ama şansınız yok, ,
R
sütunda bulunan değerler, ben takdir ediyorum "birleştirme"
Edit
büyük teşekkür ile "düzleştirmek" ve David Eisenstat'a, son algoritma şöyle görünecektir:
var A = ...;
var T = ...; // T == transpose(t), t is original matrix, algorithm works with transposed matrix
var D = 0x8040201008040201UL;
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D); T = (T << 8) | (T >> 56); D = (D << 8) | (D >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & D);
kod
aşağıdaki parça:
public static void Main (string[] args){
ulong U;
var Random = new Xor128();
var timer = DateTime.Now;
var A = Random.As<IUniformRandom<UInt64>>().Evaluate();
var T = Random.As<IUniformRandom<UInt64>>().Evaluate();
var steps = 10000000;
for (var i = 0; i < steps; i++) {
ulong r = 0;
var d = 0x8040201008040201UL;
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d); T = (T << 8) | (T >> 56); d = (d << 8) | (d >> 56);
U = A & T; U |= U >> 1; U |= U >> 2; U |= U >> 4; U &= 0x0101010101010101UL; U = (U << 8) - U; r |= (U & d);
}
Console.WriteLine (DateTime.Now - timer);
var m1 = new Int32[8,8];
var m2 = new Int32[8,8];
var m3 = new Int32[8,8];
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
m1 [row, col] = Random.As<IUniformRandom<Int32>>().Evaluate(0, 1);
m2 [row, col] = Random.As<IUniformRandom<Int32>>().Evaluate(0, 1);
m3 [row, col] = Random.As<IUniformRandom<Int32>>().Evaluate(0, 1);
}
}
timer = DateTime.Now;
for (int i = 0; i < steps; i++) {
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
var sum = 0;
for (int temp = 0; temp < 8; temp++) {
sum += m1 [row, temp] * m2 [temp, row];
}
m3 [row, col] = sum;
}
}
}
Console.WriteLine (DateTime.Now - timer);
}
beni takip sonuçları gösterir:
00:00:02.4035870
00:00:57.5147150
Ve bu Mac OS X/Mono altında bir 23x performans iyileştirme, teşekkürler herkes
Belki de yalnızca bir dili etiketlemelisiniz ... – PlasmaHH
Sadece [tag: pseudocode] veya (bir algoritma sorusuysa) [tag: algoritm] ** yerine ** herhangi bir dil etiketi sorun değilse bir dile. – Dukeling
'matrix' etiketini' algoritma 'olarak değiştirdiniz, bu sizin için uygun mu? – Lu4