有几种使用SIMD指令优化HOG描述符计算的尝试:OpenCV、Dlib和SIMD。它们都使用标量代码将结果幅值添加到HOG直方图中:
float histogram[height/8][width/8][18];
float ky[height], kx[width];
int idx[size];
float val[size];
for(size_t i = 0; i < size; ++i)
{
histogram[y/8][x/8][idx[i]] += val[i]*ky[y]*kx[x];
histogram[y/8][x/8 + 1][idx[i]] += val[i]*ky[y]*kx[x + 1];
histogram[y/8 + 1][x/8][idx[i]] += val[i]*ky[y + 1]*kx[x];
histogram[y/8 + 1][x/8 + 1][idx[i]] += val[i]*ky[y + 1]*kx[x + 1];
}
在那里,大小的值取决于实现,但一般意义相同。
我知道使用SIMD计算直方图的问题并没有简单有效的解决方案。但在这种情况下,我们有小尺寸(18)的直方图。它能帮助SIMD优化吗?
通过使用SIMD计算所有(展平的)直方图索引和bin增量,可以进行部分优化。然后在标量循环中处理这些。您可能还想将其剥离,以便一次处理一行,以便在缓存中保留临时bin索引和增量。由于使用了临时中间缓冲区,这似乎效率低下,但在实践中,我发现在类似的场景中总体上有了有益的提高。
uint32_t i = 0;
for (y = 0; y < height; ++y) // for each row
{
uint32_t inds[width * 4]; // flattened histogram indices for this row
float vals[width * 4]; // histogram bin increments for this row
// SIMD loop for this row - calculate flattened histogram indices and bin
// increments (scalar code shown for reference - converting this loop to
// SIMD is left as an exercise for the reader...)
for (x = 0; x < width; ++x, ++i)
{
indices[4*x] = (y/8)*(width/8)*18+(x/8)*18+idx[i];
indices[4*x+1] = (y/8)*(width/8)*18+(x/8 + 1)*18+idx[i];
indices[4*x+2] = (y/8+1)*(width/8)*18+(x/8)*18+idx[i];
indices[4*x+3] = (y/8+1)*(width/8)*18+(x/8 + 1)*18+idx[i];
vals[4*x] = val[i]*ky[y]*kx[x];
vals[4*x+1] = val[i]*ky[y]*kx[x+1];
vals[4*x+2] = val[i]*ky[y+1]*kx[x];
vals[4*x+3] = val[i]*ky[y+1]*kx[x+1];
}
// scalar loop for this row
float * const histogram_base = &histogram[0][0][0]; // pointer to flattened histogram
for (x = 0; x < width * 4; ++x) // for each set of 4 indices/increments in this row
{
histogram_base[indices[x]] += vals[x]; // update the (flattened) histogram
}
}
我找到了解决办法。它是一个临时缓冲区。首先,我们将直方图和临时缓冲区相加(这个操作可以矢量化)。然后,我们将缓冲区和添加到输出直方图中(此操作也可以矢量化):
float histogram[height/8][width/8][18];
float ky[height], kx[width];
int idx[size];
float val[size];
float buf[18][4];
for(size_t i = 0; i < size; ++i)
{
buf[idx[i]][0] += val[i]*ky[y]*kx[x];
buf[idx[i]][1] += val[i]*ky[y]*kx[x + 1];
buf[idx[i]][2] += val[i]*ky[y + 1]*kx[x];
buf[idx[i]][3] += val[i]*ky[y + 1]*kx[x + 1];
}
for(size_t i = 0; i < 18; ++i)
{
histogram[y/8][x/8][i] += buf[i][0];
histogram[y/8][x/8 + 1][i] += buf[i][1];
histogram[y/8 + 1][x/8][i] += buf[i][2];
histogram[y/8 + 1][x/8 + 1][i] += buf[i][3];
}
这将是我发布的第一个问题! 我正在尝试使用Intel的SSE4优化立体视觉应用程序的“块匹配”实现。2和/或AVX内部函数。我用“绝对差之和”来寻找最佳匹配块。在我的情况下,blockSize将是一个奇数,例如3或5。这是我的C代码片段: 我知道,数据流单指令多数据扩展指令集包含许多指令,以便于使用SAD进行块匹配,例如mm\u mpsadbw\u epu8和mm\u SAD\u epu8,但它们
我有int的向量,我需要找到并用特定的值替换一些元素。他们都是一样的 例如:将所有元素的4替换为8。 我正在尝试c中循环中的直接内存访问。但对我来说还是很慢。 更新: 我正在上使用OpenCV对象: 函数仅在释放模式下通过指针返回值
问题内容: 我试图与我正在阅读的有关SQL Server查询性能的书的作者联系,但似乎本书中提供的电子邮件地址已不复存在。因此,我决定向社区询问。我正在粘贴我在下面写的消息。提前致谢。 ====== 我已经购买了您的书(蒸馏而成的SQL Server 2008查询性能调优),并且知道我的SQL Server Express Edition将不支持运行必要的性能测试所需的许多重要工具。正如您已经说过
HOG-Pedestrian-Detector This repository contains the code for a MATLAB implementation of a basic HOG + SVM pedestrian detector form my Computer Science Master thesis Disclaimer If you are going to use
我想尝试使用SIMD指令编写一个atoi实现,以包含在RapidJSON(一个C JSON阅读器/写入器库)中。它目前在其他地方进行了一些SSE2和SSE4.2优化。 如果是速度增益,可以并行完成多个结果。这些字符串最初来自JSON数据的缓冲区,因此多原子函数必须执行任何所需的滑动。 我提出的算法如下: 我可以用以下方式初始化长度为N的向量:[10^N..10^1] 我将缓冲区中的每个字符转换为一
这个问题真的很奇怪。 我正在将一个例程转换为SIMD指令(我对SIMD编程非常陌生),但遇到以下代码位的问题: 问题:假设有一个SIMD实现,我只是试图计算一个正确的向量进行处理,那么处理依赖于它以前的值的正确方法是什么? 反过来,类似于函数编程的折叠实现也同样有用,因为我试图理解如何更好地提升数据依赖性,而不是为了优化而进行优化。 最后,如果你能推荐一些文献,请做。不知道如何谷歌这个话题。