C rotl32替代品

时间:2017-02-11 16:08:25

标签: c opencl

C语言中有rotl32的替代方法吗?

我发现了这个:Near constant time rotate that does not violate the standards 但仍试图获得优化的

我的代码:

k0 = rotl32 ((k3 ^ k2 ^ k ^ k0), 1u)

3 个答案:

答案 0 :(得分:1)

我认为这是最好的便携式选项:

uint32_t rotl32(uint32_t var, uint32_t hops)
{
    return (var << hops) | (var >> (32 - hops));
}

答案 1 :(得分:1)

你的问题中有opencl标签,所以内核

__kernel void rotateGpu(__global unsigned int * a,__global unsigned int * b)
{
  int idx = get_global_id(0);
  unsigned int a0=a[idx];
    for(int i=0;i<100;i++)
        a0=rotate(a0,1280u);
  b[idx] = rotate(a0,1280u);

}   
根据基准测试,在R7-240 GPU上的表现为{p> rotate

3200个无符号整数的元素数组,如a0,内核执行需要16ms,每个线程执行100次(10次1次)旋转1280u步长(因此延迟与步长无关) ))。它超过200 Gflops(但整数)达到理论最大值的40%。也许它对于整数而言比浮点数更快(我认为它们在转换后需要归一化)。

示例:

__kernel void rotateGpu(__global unsigned int * a,__global unsigned int * b)
{
  int idx = get_global_id(0);
  unsigned int a0=a[idx];

  b[idx] = rotate(a0,2u);

}   

输入:

        buf[0] = 80;
        buf[1] = 12;
        buf[2] = 14;
        buf[3] = 5 ;
        buf[4] = 70;

输出:

320 
48 
56 
20 
280

答案 2 :(得分:0)

dromtrund发布了一个很好的便携式解决方案:

uint32_t rotl32(uint32_t var, uint32_t hops) {
    return (var << hops) | (var >> (32 - hops));
}

不幸的是,此函数对hops == 0具有未定义的行为。在x86处理器上,只有hops的低位比特很重要。这种行为可以这样强制:

uint32_t rotl32(uint32_t var, uint32_t hops) {
    return (var << hops) | (var >> ((32 - hops) & 31));
}

两个函数都可以使用gcc 4.9及更高版本编译为最佳代码,可以使用Godbolt's Compiler Explorer进行验证,可以使用interesting blog article进行验证。

John Regehr对此主题有https://github.com/styled-components/styled-components/issues/124