gpt4 book ai didi

c++ - 优化 block 位操作 : base-4 numbers

转载 作者:行者123 更新时间:2023-11-30 01:47:00 25 4
gpt4 key购买 nike

这应该是一个有趣的问题,至少对我而言。

我的意图是操纵base-4 数字,编码为无符号整数。然后,每个两位 block 代表一个 base-4 数字,从最低有效位开始:

01 00 11 = base4(301)

我想使用 SSE 指令优化我的代码,因为我不确定我在这里的得分如何,也许很差。

代码从字符串开始(并使用它们来检查正确性),并实现:

  • 字符串转二进制
  • 二进制转字符串
  • 反转数字

任何提示都非常受欢迎!

uint32_t tobin(std::string s)
{
uint32_t v, bin = 0;

// Convert to binary
for (int i = 0; i < s.size(); i++)
{
switch (s[i])
{
case '0':
v = 0;
break;

case '3':
v = 3;
break;

case '1':
v = 1;
break;

case '2':
v = 2;
break;

default:
throw "UNKOWN!";
}

bin = bin | (v << (i << 1));
}

return bin;
}

std::string tostr(int size, const uint32_t v)
{
std::string b;

// Convert to binary
for (int i = 0; i < size; i++)
{
uint32_t shl = 0, shr = 0, q;

shl = (3 << (i << 1));
shr = i << 1;
q = v & shl;
q = q >> shr;

unsigned char c = static_cast<char>(q);

switch (c)
{
case 0:
b += '0';
break;

case 3:
b += '3';
break;

case 1:
b += '1';
break;

case 2:
b += '2';
break;

default:
throw "UNKOWN!";
}
}

return b;
}

uint32_t revrs(int size, const uint32_t v)
{
uint32_t bin = 0;

// Convert to binary
for (int i = 0; i < size; i++)
{
uint32_t shl = 0, shr = 0, q;

shl = (3 << (i << 1));
shr = i << 1;
q = v & shl;
q = q >> shr;

unsigned char c = static_cast<char>(q);

shl = (size - i - 1) << 1;

bin = bin | (c << shl);
}

return bin;
}

bool ckrev(std::string s1, std::string s2)
{
std::reverse(s1.begin(), s1.end());

return s1 == s2;
}

int main(int argc, char* argv[])
{
// Binary representation of base-4 number
uint32_t binr;

std::vector<std::string> chk { "123", "2230131" };

for (const auto &s : chk)
{
std::string b, r;
uint32_t c;

binr = tobin(s);
b = tostr(s.size(), binr);
c = revrs(s.size(), binr);
r = tostr(s.size(), c);

std::cout << "orig " << s << std::endl;
std::cout << "binr " << std::hex << binr << " string " << b << std::endl;
std::cout << "revs " << std::hex << c << " string " << r << std::endl;
std::cout << ">>> CHK " << (s == b) << " " << ckrev(r, b) << std::endl;
}

return 0;
}

最佳答案

这对 SSE 来说有点挑战,因为几乎没有位打包的规定(你想从每个字符中取出两个位并将它们连续打包)。无论如何,特殊指令_mm_movemask_epi8 可以帮助你。

对于字符串到二进制的转换,您可以进行如下操作:

  • 加载 16 个字符的字符串(如有必要,用零填充或在加载后清除);

  • 按字节减去 ASCII 零。

  • 将字节“无符号大于”与 16 个“3”字节的字符串进行比较;这将在任何有无效字符的地方设置字节 0xFF

  • 使用_mm_movemask_epi8检测压缩短值中的此类字符

如果一切正常,您现在需要打包位对。为此你需要

  • 复制16个字节

  • 将权重 1 和 2 的位向左移动 7 或 6 个位置,使它们最重要(_mm_sll_epi16。没有 epi8 版本,但是一个元素的位在另一个元素的低位中变成垃圾对此并不重要。)

  • 将它们交错放置(_mm_unpack..._epi8,一次用 lo,一次用 hi)

  • 使用 _mm_movemask_epi8 将这两个 vector 的高位存储到 short 中。

对于二进制到字符串的转换,我想不出一个有意义的 SSE 实现,因为没有 _mm_movemask_epi8 的对应物可以让您有效地解包。

关于c++ - 优化 block 位操作 : base-4 numbers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32272324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com