- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是计算缓冲区中不同值数量的基本算法:
unsigned getCount(const uint8_t data[16])
{
uint8_t pop[256] = { 0 };
unsigned count = 0;
for (int i = 0; i < 16; ++i)
{
uint8_t b = data[i];
if (0 == pop[b])
count++;
pop[b]++;
}
return count;
}
是否可以通过加载到 q-reg 并施展魔法,以某种方式在 neon 中有效地完成此操作?或者,我是否可以有效地说 data
具有相同的所有元素,或者仅包含两个或两个以上的不同值?
例如,使用 vminv_u8
和 vmaxv_u8
我可以找到最小和最大元素,如果它们相等,我知道 data
具有相同的元素.如果不是,那么我可以用最小值 vceq_u8
和用最大值 vceq_u8
然后 vorr_u8
这些结果并比较我所有的 1-s在结果中。基本上,在 NEON 中,它可以通过这种方式完成。有什么想法可以让它变得更好吗?
unsigned getCountNeon(const uint8_t data[16])
{
uint8x16_t s = vld1q_u8(data);
uint8x16_t smin = vdupq_n_u8(vminvq_u8(s));
uint8x16_t smax = vdupq_n_u8(vmaxvq_u8(s));
uint8x16_t res = vdupq_n_u8(1);
uint8x16_t one = vdupq_n_u8(1);
for (int i = 0; i < 14; ++i) // this obviously needs to be unrolled
{
s = vbslq_u8(vceqq_u8(s, smax), smin, s); // replace max with min
uint8x16_t smax1 = vdupq_n_u8(vmaxvq_u8(s));
res = vaddq_u8(res, vaddq_u8(vceqq_u8(smax1, smax), one));
smax = smax1;
}
res = vaddq_u8(res, vaddq_u8(vceqq_u8(smax, smin), one));
return vgetq_lane_u8(res, 0);
}
通过一些优化和改进,或许可以用 32-48 条 neon 指令处理一个 16 字节的 block 。这可以在 ARM 上做得更好吗?不太可能
我问这个问题的一些背景。当我在研究一种算法时,我正在尝试不同的方法来处理数据,但我不确定最后我会使用什么。可能有用的信息:
所以,我正在尝试一些东西,在我使用任何方法之前,我想看看该方法是否可以得到很好的优化。例如,每个 block 的平均值基本上是 arm64 上的 memcpy 速度。
最佳答案
如果您期望有很多重复项,并且可以高效使用vminv_u8
获得水平最小值,这可能比标量更好.或者不是,也许 NEON->ARM 因循环条件而停顿杀死它。 >.< 但是应该可以通过展开来缓解这种情况(并在寄存器中保存一些信息以确定您超出了多少)。
// pseudo-code because I'm too lazy to look up ARM SIMD intrinsics, edit welcome
// But I *think* ARM can do these things efficiently,
// except perhaps the loop condition. High latency could be ok, but stalling isn't
int count_dups(uint8x16_t v)
{
int dups = (0xFF == vmax_u8(v)); // count=1 if any elements are 0xFF to start
auto hmin = vmin_u8(v);
while (hmin != 0xff) {
auto min_bcast = vdup(hmin); // broadcast the minimum
auto matches = cmpeq(v, min_bcast);
v |= matches; // min and its dups become 0xFF
hmin = vmin_u8(v);
dups++;
}
return dups;
}
这会将唯一值变成 0xFF,一次一组重复项。
循环携带的dep链通过v/hmin停留在 vector 寄存器中;只有循环分支需要 NEON->integer。
按 8 展开,hmin
上没有分支,将结果留在 8 个 NEON 寄存器中。然后转移这8个值; back-to-back transfers of multiple NEON registers to ARM only incurs one total stall (Jake 测试的 14 个周期中的任何一个。)乱序执行也可以隐藏一些对这个停顿的惩罚。然后用完全展开的整数循环检查这 8 个整数寄存器。
将展开因子调整得足够大,这样您通常就不需要对大多数输入 vector 进行另一轮 SIMD 运算。如果几乎所有 vector 最多有 5 个唯一值,则展开 5 而不是 8。
不是将多个 hmin
结果转换为整数,而是用 NEON 计数。如果您可以使用 ARM32 NEON 部分寄存器技巧免费将多个 hmin
值放入同一个 vector 中,那么将其中的 8 个值洗牌到一个 vector 中并比较不等于0xFF
。然后水平添加该比较结果以获得 -count
。
或者,如果您在单个 vector 的不同元素中有来自不同输入 vector 的值,则可以使用垂直运算一次为多个输入 vector 添加结果,而无需水平运算。
几乎肯定有优化空间,但我不太了解 ARM,或 ARM 性能细节。 NEON 很难用于任何条件,因为 NEON-> 整数的性能损失很大,这与 x86 完全不同。 Glibc has a NEON memchr
在循环中使用 NEON->integer,但我不知道它是否使用它或者它是否比标量更快。
每次都将 256 字节缓冲区清零的代价很高,但我们不需要这样做。 使用序列号以避免需要重置:
++seq
;对于集合中的每个元素:
sum += (histogram[i] == seq);
histogram[i] = seq; // no data dependency on the load result, unlike ++
您可以将直方图设为 uint16_t
或 uint32_t
的数组,以避免在 uint8_t seq
回绕时需要重新归零。但随后它会占用更多的缓存空间,因此也许只是将每 254 个序列号重新归零是最有意义的。
关于c++ - 有效地计算 arm neon 中 16 字节缓冲区中不同值的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49993056/
SQL 和一般开发的新手,我有一个表(COUNTRIES),其中包含字段(INDEX、NAME、POPULATION、AREA) 通常我添加一个客户端(Delphi)计算字段(DENSITY)和 On
我想使用 calc(100%-100px),但在我的 demo 中不起作用由于高度只接受像素,因此如何将此百分比值转换为像素。 最佳答案 以下将为您提供高度: $(window).height();
我正在尝试在 MySQL 中添加列并动态填充其他列。 例如我有一张表“数字”并具有第 1 列、第 2 列、第 3 列,这些总数应填充在第 4 列中 最佳答案 除非我误解了你的问题,否则你不只是在寻找:
我想返回简单计算的结果,但我不确定如何执行此操作。我的表格如下: SELECT COUNT(fb.engineer_id) AS `total_feedback`, SUM(fb.ra
我一直在尝试做这个程序,但我被卡住了,我仍然是一个初学者,任何帮助将不胜感激。我需要程序来做 打印一个 10 X 10 的表格,其中表格中的每个条目都是行号和列号的总和 包含一个累加器,用于计算所有表
这个计算背后一定有一些逻辑。但我无法得到它。普通数学不会导致这种行为。谁能帮我解释一下原因 printf ("float %f\n", 2/7 * 100.0); 结果打印 1.000000 为什么会
我想计算从 0 到 (n)^{1/2} - 1 的数字的 AND每个数字从 0 到 (n)^{1/2} - 1 .我想在 O(n) 中执行此操作时间,不能使用 XOR、OR、AND 运算。 具体来说,
如何在 Excel 中将公式放入自定义数字格式?例如(出于说明目的随机示例), 假设我有以下数据: 输入 输出 在不编辑单元格中的实际数据的情况下,我想显示单元格中的值除以 2,并保留两位小数: 有没
每次我在 Flutter 应用程序中调用计算()时,我都会看到内存泄漏,据我所知,这基本上只是一种生成隔离的便捷方法。我的应用程序内存占用增加并且在 GC 之后永远不会减少。 我已将我的代码简化为仅调
我有数字特征观察 V1通过 V12用于目标变量 Wavelength .我想计算 Vx 之间的 RMSE列。数据格式如下。 每个变量“Vx”以 5 分钟的间隔进行测量。我想计算所有 Vx 变量的观测值
我正在寻找一种使用 C 语言计算文件中未知字符数的简单方法。谢谢你的帮助 最佳答案 POSIX 方式(可能是您想要的方式): off_t get_file_length( FILE *file ) {
我正在使用 Postgres,并且我正试图围绕如何在连续日期跨度中得出第一个开始日期的问题进行思考。例如 :- ID | Start Date | End Date =================
我有一个订单表格,我在其中使用 jQuery 计算插件来汇总总数。 此求和工作正常,但生成的“总和”存在问题。总之,我希望用逗号替换任何点。 代码的基础是; function ($this) {
我在使用 double 变量计算简单算术方程时遇到问题。 我有一个具有 double 属性 Value 的组件,我将此属性设置为 100。 然后我做一个简单的减法来检查这个值是否真的是 100: va
我在这里看到了一些关于 CRC 32 计算的其他问题。但没有一个让我满意,因此是这样。 openssl 库是否有任何用于计算 CRC32 的 api 支持?我已经在为 SHA1 使用 openssl,
当我在PHP日期计算中遇到问题时,我感到惊讶。 $add = '- 30 days'; echo date('Y-m-01', strtotime($add)); // result is 2017-
我正在使用 javascript 进行练习,我编写了这个脚本来计算 2 个变量的总和,然后在第三个方程中使用这个总和!关于如何完成这项工作的任何想法都将非常有用! First Number:
我有一个来自EAC的提示单和一个包含完整专辑的FLAC文件。 我正在尝试制作一些python脚本来播放文件,因为我需要能够设置在flac文件中开始的位置。 如何从CueSheet格式MM:SS:FF转
这个问题已经有答案了: Adding two numbers concatenates them instead of calculating the sum (24 个回答) 已关闭去年。 我有一个
4000 我需要上面字段 name="quantity" 和 id="price" 中的值,并使用 javascript 函数进行计算,并将其显示在字段 id= 中仅当我单击计算按钮时才显示“总
我是一名优秀的程序员,十分优秀!