首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Intrinsics中Neon的校验和代码实现

Intrinsics中Neon的校验和代码实现
EN

Stack Overflow用户
提问于 2012-08-22 05:46:20
回答 1查看 1.3K关注 0票数 1

我试图用内禀实现霓虹灯的校验和计算代码(2的补码加法)。当前的校验和计算正在ARM上进行。

我的实现一次从内存中获取128位到霓虹灯寄存器并执行SIMD (加法),结果从128位数折叠成16位数。

一切看起来都很好,但是我的霓虹灯实现比ARM版本花费更多的时间。

ARM版本采取:0.860000 s霓虹灯版本采取:1.260000 s

注:

  1. 使用"time.h“中的实用程序进行剖析
  2. 校验和函数从示例应用程序调用10,000次,并在所有函数完成运行后计算时间。

其他详细信息:

  1. 使用GNU工具链( arm -none-linux-gnueabi-gcc)编译内部代码,而不是arm工具链。
  2. Linux平台。
  3. C-固有代码。

问题:

  1. 为什么霓虹灯版本比ARM版本花费更多的时间?(虽然我已经注意到在批处理中使用了具有最小周期的内部循环)
  2. 如何实现我想要达到的目标?(利用霓虹灯的效率)
  3. 有人能指点我或分享一些示例实现(伪代码/算法/代码,而不是理论实现文件或会谈),使用臂氖相互作用在一起?

任何帮助都将不胜感激。

这是我的密码:

代码语言:javascript
复制
uint16_t do_csum(const unsigned char * buff, int len)
{
int odd, count, i;

uint32x4_t result = veorq_u32( result, result), sum = veorq_u32( sum, sum); 
uint16x4_t data, data_hi, data_low, data8;
uint16x8_t dataq;
uint16_t result16, disp[20] = {0,0,0,0,0,0,0,0,0,0};

if (len <= 0)
    goto out;
odd = 1 & (unsigned long) buff;
if (odd) {
    uint8x8_t data1 = veor_u8( data1, data1); 
    data1 = (uint16x4_t)vld1_lane_u8((uint8_t *)buff, data1, 0); //result = *buff << 8;
    data1 = (uint16x4_t)vshl_n_u16( data1, 8);

    len--;
    buff++;
    result = vaddw_u16(result, data1);
}
count = len >> 1;       /* nr of 16-bit words.. */
if (count) {
    if (2 & (unsigned long) buff) {
        uint16x4_t data2 = veor_u16( data2, data2); 
        data2 = (uint16x4_t) vld1_lane_u16((uint16_t *)buff, data2, 0); //result += *(unsigned short *) buff;
        count--;
        len -= 2;
        buff += 2;
        result = vaddw_u16( result, data2);
    }
    count >>= 1;        /* nr of 32-bit words.. */
    if (count) {
        if (4 & (unsigned long) buff) {
            uint32x2_t data4 = (uint16x4_t) vld1_lane_u32((uint32_t *) buff, data4, 0);
            count--;
            len -= 4;
            buff += 4;
            result = vaddw_u16( result, data4);
        }
        count >>= 1;    /* nr of 64-bit words.. */
        if (count) {
            if (8 & (unsigned long) buff) {
                uint64x1_t data8 = vld1_u64((uint64_t *) buff); 
                count--;
                len -= 8;
                buff += 8;
                result = vaddw_u16( result,(uint16x4_t)data8);
            }
            count >>= 1;    /* nr of 128-bit words.. */
            if (count) {
                do {
                    dataq = (uint16x8_t)vld1q_u64((uint64_t *) buff); // VLD1.64 {d0, d1}, [r0]
                    count--;
                    buff += 16;

                    sum = vpaddlq_u16(dataq);   
                    vst1q_u16( disp, dataq); // VST1.16 {d0, d1}, [r0]

                    result = vaddq_u32( sum, result);
                } while (count);
            }
            if (len & 8) {
                uint64x1_t data8 =  vld1_u64((uint64_t *) buff); 
                buff += 8;
                result = vaddw_u16( result, (uint16x4_t)data8);
            }
        }
        if (len & 4) {
            uint32x2_t data4 = veor_u32( data4, data4); 

            data4 = (uint16x4_t)vld1_lane_u32((uint32_t *) buff, data4, 0);//result += *(unsigned int *) buff;
            buff += 4;
            result = vaddw_u16( result,(uint16x4_t) data4);
        }
    }
    if (len & 2) {
        uint16x4_t data2 = veor_u16( data2, data2); 
        data2 = (uint16x4_t) vld1_lane_u16((uint16_t *)buff, data2, 0); //result += *(unsigned short *) buff;
        buff += 2;
        result = vaddw_u16( result, data2);
    }
}
if (len & 1){
    uint8x8_t data1 = veor_u8( data1, data1); 
    data1 = (uint16x4_t) vld1_lane_u8((uint8_t *)buff, data1, 0); //result = *buff << 8;
    result = vaddw_u8( result, data1);
}


result16 = from128to16(result);

if (odd)
    result16 = ((result16 >> 8) & 0xff) | ((result16 & 0xff) << 8);

out:
    return result16;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-22 06:16:26

有几件事你可以改进:

  • 摆脱商店到disp -这看起来像调试代码被留在?
  • 不要在主循环中进行水平加法--只需在循环中执行部分(垂直)和,并在循环后执行最后一次水平加法(关于如何做到这一点的示例,请参见this answer --这是用于SSE的,但原理是相同的)。
  • 确保使用gcc -O3 ...从编译器优化中获得最大利益。
  • 不要用goto!(不影响表演,但是邪恶的。)
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12066964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档