我想优化直方图统计代码与霓虹灯内部。但是我没有成功。这里是c代码:
#define NUM (7*1024*1024)
uint8 src_data[NUM];
uint32 histogram_result[256] = {0};
for (int i = 0; i < NUM; i++)
{
histogram_result[src_data[i]]++;
}
直方图统计更像是串行处理。使用neon intrinsics很难进行优化。有人知道如何优化吗?提前谢谢。
您不能直接对存储进行矢量化,但可以通过管道对其进行矢量化,并且可以在32位平台上对地址计算进行矢量化(在64位平台上的矢量化程度较低)。
你要做的第一件事,实际上并不需要NEON受益,就是展开直方图数组,这样你就可以一次拥有更多的数据:
#define NUM (7*1024*1024)
uint8 src_data[NUM];
uint32 histogram_result[256][4] = {{0}};
for (int i = 0; i < NUM; i += 4)
{
uint32_t *p0 = &histogram_result[src_data[i + 0]][0];
uint32_t *p1 = &histogram_result[src_data[i + 1]][1];
uint32_t *p2 = &histogram_result[src_data[i + 2]][2];
uint32_t *p3 = &histogram_result[src_data[i + 3]][3];
uint32_t c0 = *p0;
uint32_t c1 = *p1;
uint32_t c2 = *p2;
uint32_t c3 = *p3;
*p0 = c0 + 1;
*p1 = c1 + 1;
*p2 = c2 + 1;
*p3 = c3 + 1;
}
for (int i = 0; i < 256; i++)
{
packed_result[i] = histogram_result[i][0]
+ histogram_result[i][1]
+ histogram_result[i][2]
+ histogram_result[i][3];
}
请注意,p0
到p3
永远不能指向同一地址,因此对它们的读写重新排序就可以了。
由此,您可以使用intrinsic将p0
的计算矢量化为p3
,并可以矢量化最终循环。
首先测试它(因为我没有!)。然后,您可以尝试将数组构造为result[4][256]
,而不是result[256][4]
,或者使用更小或更大的展开因子。
将某些霓虹灯内在特性应用于此:
uint32 histogram_result[256 * 4] = {0};
static const uint16_t offsets[] = { 0x000, 0x001, 0x002, 0x003,
0x000, 0x001, 0x002, 0x003 };
uint16x8_t voffs = vld1q_u16(offsets);
for (int i = 0; i < NUM; i += 8) {
uint8x8_t p = vld1_u8(&src_data[i]);
uint16x8_t p16 = vshll_n_u8(p, 16);
p16 = vaddq_u16(p16, voffs);
uint32_t c0 = histogram_result[vget_lane_u16(p16, 0)];
uint32_t c1 = histogram_result[vget_lane_u16(p16, 1)];
uint32_t c2 = histogram_result[vget_lane_u16(p16, 2)];
uint32_t c3 = histogram_result[vget_lane_u16(p16, 3)];
histogram_result[vget_lane_u16(p16, 0)] = c0 + 1;
c0 = histogram_result[vget_lane_u16(p16, 4)];
histogram_result[vget_lane_u16(p16, 1)] = c1 + 1;
c1 = histogram_result[vget_lane_u16(p16, 5)];
histogram_result[vget_lane_u16(p16, 2)] = c2 + 1;
c2 = histogram_result[vget_lane_u16(p16, 6)];
histogram_result[vget_lane_u16(p16, 3)] = c3 + 1;
c3 = histogram_result[vget_lane_u16(p16, 7)];
histogram_result[vget_lane_u16(p16, 4)] = c0 + 1;
histogram_result[vget_lane_u16(p16, 5)] = c1 + 1;
histogram_result[vget_lane_u16(p16, 6)] = c2 + 1;
histogram_result[vget_lane_u16(p16, 7)] = c3 + 1;
}
如果直方图数组展开为x8而不是x4,您可能希望使用八个标量累加器而不是四个,但您必须记住,这意味着八个计数寄存器和八个地址寄存器,这比32位ARM的寄存器多(因为您不能使用SP和PC)。
不幸的是,由于地址计算掌握在NEON Intrinsic手中,我认为编译器无法安全地推理它如何能够对读写进行重新排序,因此您必须显式地对它们进行重新排序,并希望以最好的方式进行。
我们的java流媒体服务器正在生产中运行,它需要约10GB的RAM才能运行,所以我们安装了32GB。内存会逐渐增加,直到达到限制并弹出内存不足异常。 由于直方图和内存转储数字与系统报告的内存使用量不匹配,我很难准确地指出随着时间的推移,哪些对象正在累积,也就是说,java进程占用的内存略多于最大20GB(因此内存不足异常是合理的),但直方图和内存转储显示总共使用了6.4GB。 如何在直方图中未显示
我想用python绘制一个非常简单的直方图。这是我的代码: 这就是结果 我怎样才能把这些条放在整数的地方呢?为什么我的图表也显示浮点数?
目标 我们将学习直方图均衡的概念,并用它来改善我们的图片对比度。 理论基础 考虑像素值仅限于某个特定值范围的图像。例如,较亮的图像将所有像素限制在较高的值。但是一张好的图像将会具有来自图像所有区域的像素。所以你需要将这个直方图拉伸到两端,用简单的话来说,这就是直方图均衡化所能做到的。这通常会改善图像的对比度。 我建议你阅读关于直方图均衡化的维基百科页面,了解更多细节。它解释的很好而且有相当好的例子
问题内容: 我在netbeans平台上制作了App。我想绘制直方图。我有红色,绿色和蓝色的图像像素。因此,请任何人对我提出建议,如何使用该像素值绘制直方图?我的代码在下面,其中我使用图像的红色,绿色和蓝色像素值。 问题答案:
numpy.histogram()函数将输入数组和作为两个参数。 bin数组中的连续元素用作每个bin的边界。 Matplotlib 可以将直方图的数字表示转换为图形。 pyplot子模块的plt()函数将包含数据和数组的数组作为参数,并转换为直方图。
我正在尝试使用 marplot.lib 库在 Python 中绘制直方图;但是,我一直收到此错误:“属性错误:箱必须单调增加。 这是我目前的代码: 传入的参数是信息。“信息”是一个元组列表,可能如下所示: [(4, 0.7984031936127745), (5, 0.5988023952095809), (5, 0.8739076154806492), (5, 0.736454497632824