diff options
| author | Mahmoud <[email protected]> | 2020-06-01 14:56:30 -0400 |
|---|---|---|
| committer | Mahmoud <[email protected]> | 2020-06-01 14:56:30 -0400 |
| commit | 3e580ee62a9cc8010930f692d8a6201a31ed77e0 (patch) | |
| tree | be6af48c39a4615c951f66b4ea936ae085e418da /src/gpgpu-sim/addrdec.cc | |
| parent | b53dcfc7b079a06f26b25cedcc09c4843ef1a6b9 (diff) | |
moving all ipoly equstions to one file
Diffstat (limited to 'src/gpgpu-sim/addrdec.cc')
| -rw-r--r-- | src/gpgpu-sim/addrdec.cc | 149 |
1 files changed, 39 insertions, 110 deletions
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 91ba47f..c01b8fa 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -31,9 +31,12 @@ #include <string.h> #include "../option_parser.h" #include "gpu-sim.h" +#include "hashing.h" static long int powli(long int x, long int y); static unsigned int LOGB2_32(unsigned int v); +static unsigned next_powerOf2(unsigned n); + static new_addr_type addrdec_packbits(new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low); static void addrdec_getmasklimit(new_addr_type mask, unsigned char *high, @@ -133,121 +136,29 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, break; case BITWISE_PERMUTATION: { assert(!gap); - tlx->chip = (tlx->chip) ^ (rest_of_addr_high_bits & (m_n_channel - 1)); + tlx->chip = + bitwise_hash_function(rest_of_addr_high_bits, tlx->chip, m_n_channel); assert(tlx->chip < m_n_channel); break; } case IPOLY: { - /* - * Set Indexing function from "Pseudo-randomly interleaved memory." - * Rau, B. R et al. - * ISCA 1991 - * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf - * - * equations are corresponding to IPOLY(37) and are adopted from: - * "Sacat: streaming-aware conflict-avoiding thrashing-resistant gpgpu - * cache management scheme." Khairy et al. IEEE TPDS 2017. - * - * equations for 32 banks are corresponding to IPOLY(37) - * equations for 64 banks are corresponding to IPOLY(67) - * To see all the IPOLY equations for all the degrees, see - * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf - * - * We generate these equations using GF(2) arithmetic: - * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 - * - * We go through all the strides 128 (10000000), 256 (100000000),... and - * do modular arithmetic in GF(2) Then, we create the H-matrix and group - * each bit together, for more info read the ISCA 1991 paper - * - * IPOLY hashing guarantees conflict-free for all 2^n strides which widely - * exit in GPGPU applications and also show good performance for other - * strides. - */ - assert(!gap); - if (m_n_channel == 32 && m_n_sub_partition_in_channel == 1) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<5> chip(tlx->chip); - chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ - a[0] ^ chip[0]; - chip[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ - a[1] ^ chip[1]; - chip[2] = a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ - a[0] ^ chip[2]; - chip[3] = - a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ chip[3]; - chip[4] = - a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ chip[4]; - tlx->chip = chip.to_ulong(); - break; - } else if (m_n_channel == 16 && m_n_sub_partition_in_channel == 2) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<4> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ - a[0] ^ chip[0]; - chip[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ - a[1] ^ chip[1]; - chip[2] = a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ - a[0] ^ chip[2]; - chip[3] = - a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ chip[3]; - tlx->chip = chip.to_ulong(); - unsigned par_id = - a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; - } else if (m_n_channel == 32 && m_n_sub_partition_in_channel == 2) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<5> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[18] ^ a[17] ^ a[16] ^ a[15] ^ a[12] ^ a[10] ^ a[6] ^ a[5] ^ - a[0] ^ chip[0]; - chip[1] = a[15] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[5] ^ a[1] ^ - a[0] ^ chip[1]; - chip[2] = a[16] ^ a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[8] ^ a[6] ^ a[2] ^ - a[1] ^ chip[2]; - chip[3] = a[17] ^ a[15] ^ a[14] ^ a[13] ^ a[12] ^ a[9] ^ a[7] ^ a[3] ^ - a[2] ^ chip[3]; - chip[4] = a[18] ^ a[16] ^ a[15] ^ a[14] ^ a[13] ^ a[10] ^ a[8] ^ a[4] ^ - a[3] ^ chip[4]; - tlx->chip = chip.to_ulong(); - unsigned par_id = - a[17] ^ a[16] ^ a[15] ^ a[14] ^ a[11] ^ a[9] ^ a[5] ^ a[4] ^ bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; - } else { /* Else incorrect number of channels for the hashing function */ - assert( - "\nGPGPU-Sim memory_partition_indexing error: The number of " - "channels should be " - "32 or 64 for the hashing IPOLY index function.\n" && - 0); - } - assert(tlx->chip < m_n_channel); - break; - } - case PAE: { - // Page Address Entropy - // random selected bits from the page and bank bits - // similar to - // Liu, Yuxi, et al. "Get Out of the Valley: Power-Efficient Address - assert(!gap); - std::bitset<64> a(tlx->row); - std::bitset<5> chip(tlx->chip); - std::bitset<4> b(tlx->bk); - chip[0] = a[13] ^ a[10] ^ a[9] ^ a[5] ^ a[0] ^ b[3] ^ b[0] ^ chip[0]; - chip[1] = a[12] ^ a[11] ^ a[6] ^ a[1] ^ b[3] ^ b[2] ^ b[1] ^ chip[1]; - chip[2] = a[14] ^ a[9] ^ a[8] ^ a[7] ^ a[2] ^ b[1] ^ chip[2]; - chip[3] = a[11] ^ a[10] ^ a[8] ^ a[3] ^ b[2] ^ b[3] ^ chip[3]; - chip[4] = a[12] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ b[1] ^ b[0] ^ chip[4]; - tlx->chip = chip.to_ulong(); + // assert(!gap); + unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1; + unsigned sub_partition = tlx->chip * m_n_sub_partition_in_channel + + (tlx->bk & sub_partition_addr_mask); + sub_partition = ipoly_hash_function( + rest_of_addr_high_bits, sub_partition, + nextPowerOf2_m_n_channel * m_n_sub_partition_in_channel); + + if (gap) // if it is not 2^n partitions, then take modular + sub_partition = + sub_partition % (m_n_channel * m_n_sub_partition_in_channel); + + tlx->chip = sub_partition / m_n_channel; + tlx->sub_partition = sub_partition; assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; break; } case RANDOM: { @@ -377,6 +288,8 @@ void linear_to_raw_address_translation::init( log2sub_partition = ::LOGB2_32(n_sub_partition_in_channel); m_n_channel = n_channel; m_n_sub_partition_in_channel = n_sub_partition_in_channel; + nextPowerOf2_m_n_channel = ::next_powerOf2(n_channel); + m_n_sub_partition_total = n_channel * n_sub_partition_in_channel; gap = (n_channel - ::powli(2, nchipbits)); if (gap) { @@ -663,6 +576,22 @@ static unsigned int LOGB2_32(unsigned int v) { return r; } +// compute power of two greater than or equal to n +// https://www.techiedelight.com/round-next-highest-power-2/ +unsigned next_powerOf2(unsigned n) { + // decrement n (to handle the case when n itself + // is a power of 2) + n = n - 1; + + // do till only one bit is left + while (n & n - 1) n = n & (n - 1); // unset rightmost bit + + // n is now a power of two (less than n) + + // return next power of 2 + return n << 1; +} + static new_addr_type addrdec_packbits(new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low) { unsigned pos = 0; |
