这个霓虹灯代码的速度在ndk中不稳定

Posted

技术标签:

【中文标题】这个霓虹灯代码的速度在ndk中不稳定【英文标题】:the speed of this neon code is not stable in ndk 【发布时间】:2016-08-02 10:24:52 【问题描述】:

我有一段代码有时需要 0.1 毫秒,但有时需要 10 毫秒,有没有人可以为我提供一些建议

        for (uint32_t k = 0; k < 32; k++, dataOff += stp)
        
            uint8x16_t d0 = vld1q_u8((const uint8_t *)dataOff);
            uint8x16_t d1 = vld1q_u8((const uint8_t *)(dataOff + 16));
            maxValue = vmaxq_u8(maxValue, vmaxq_u8(d0, d1));
            minValue = vminq_u8(minValue, vminq_u8(d0, d1));
        
        maxValue1 = vmax_u8(vget_high_u8(maxValue), vget_low_u8(maxValue));
        minValue1 = vmin_u8(vget_high_u8(minValue), vget_low_u8(minValue));
        maxValue1 = vmax_u8(maxValue1, vext_u8(maxValue1, maxValue1, 4));
        minValue1 = vmin_u8(minValue1, vext_u8(minValue1, minValue1, 4));
        maxValue1 = vmax_u8(maxValue1, vext_u8(maxValue1, maxValue1, 2));
        minValue1 = vmin_u8(minValue1, vext_u8(minValue1, minValue1, 2));

        maxValueUchar = __max(vget_lane_u8(maxValue1, 0), vget_lane_u8(maxValue1, 1));
        minValueUchar = __min(vget_lane_u8(minValue1, 0), vget_lane_u8(minValue1, 1));

        if (maxValueUchar - minValueUchar < hist_th_grid)continue;//bright delta < 64, NO
        else if (maxValueUchar < hist_th_grid)continue;//all dark, NO

        dataOff = data;
        uint16x8_t sum = vdupq_n_u16(0);
        uint32x4_t sum32;
        uint8_t sumInt;
        for (uint32_t k = 0; k < 32; k++, dataOff += stp)
        
            uint8x16_t d0 = vld1q_u8((const uint8_t *)dataOff);
            uint8x16_t d1 = vld1q_u8((const uint8_t *)(dataOff + 16));
            sum = vaddq_u16(sum, vaddq_u16(vpaddlq_u8(d0), vpaddlq_u8(d1)));
        
        sum32 = vpaddlq_u16(sum);
        sum32 = vaddq_u32(sum32, vextq_u32(sum32, sum32, 2));
        sum32 = vaddq_u32(sum32, vextq_u32(sum32, sum32, 1));
        sumInt = __min((vgetq_lane_u32(sum32, 0) >> 10) + brt_th_grid,255u);

而且我发现这段代码在三星galaxy s6中的速度比三星galaxy s7更稳定,有没有人能告诉我为什么

【问题讨论】:

你是怎么测量的? 我用opencv的 cv::getTickCount() ,我觉得测量是正确的 你需要展示你的测试循环,这更有可能是错误的来源。 测量不仅仅是您调用的函数。除了下面提到的频率缩放问题(这是一个很大的问题)。您是否正在为一个有意义的刻度分辨率倍数运行测试(使用 getTickFrequency 然后生成一个运行该数量长度数千倍的测试以确保良好的精度)?一旦你的测试运行了很长时间,那么你就会遇到其他问题......你是否阻止其他线程同时运行?算法可以切换影响缓存的 CPU(cpu 亲和类型的东西)吗? 【参考方案1】:

所有现代智能手机都使用动态频率缩放来平衡 CPU 和内存系统性能与电池寿命,大多数高端设备三星芯片组也使用具有两种不同 CPU 设计(ARM“big.LITTLE”)的异构 SMP。

如果你运行的是短代码sn-ps,“big @ max frequency”和“LITTLE @ min frequency”之间的性能会有很大差异;尤其是因为 LITTLE 内核上的 NEON 性能是为效率而不是最大性能而设计的,因此会比大内核慢得多。

一般而言,这意味着在进行基准测试时,理想情况下您需要稳定的持续工作负载几秒钟来预热设备,以便在运行您实际想要测量的代码之前让频率和 CPU 选择稳定下来.

【讨论】:

以上是关于这个霓虹灯代码的速度在ndk中不稳定的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 小技巧之霓虹灯文本的「故障」效果的实现

霓虹灯代码没有优化

为 iOS 编译半浮动霓虹灯指令

如何制作漂亮的霓虹灯效果?

161-电池按钮酷炫霓虹灯悬停特效

卤化物是不是支持带有霓虹灯的 ARMv8(aarch64)?