【发布时间】:2011-12-14 18:10:11
【问题描述】:
假设我有一个数组
k = [1 2 0 0 5 4 0]
我可以如下计算掩码
m = k > 0 = [1 1 0 0 1 1 0]
仅使用掩码 m 和以下操作
- 左/右移动
- 和/或
- 加/减/乘
我可以将 k 压缩成以下
[1 2 5 4]
这是我目前的做法(MATLAB 伪代码):
function out = compact( in )
d = in
for i = 1:size(in, 2) %do (# of items in in) passes
m = d > 0
%shift left, pad w/ 0 on right
ml = [m(2:end) 0] % shift
dl = [d(2:end) 0] % shift
%if the data originally has a gap, fill it in w/ the
%left shifted one
use = (m == 0) & (ml == 1) %2 comparison
d = use .* dl + ~use .* d
%zero out elements that have been moved to the left
use_r = [0 use(1:end-1)]
d = d .* ~use_r
end
out = d(1 : size(find(in > 0), 2)) %truncate the end
end
直觉
每次迭代,我们将掩码向左移动并比较掩码。如果我们发现在这个移位之后,原来是 void(mask[i] = 0) 的索引现在是有效的(mask[i] = 1),我们设置一个索引来让数据左移。
问题
上面的算法有 O(N * (3 shift + 2 comparison + AND + add + 3 multiplis))。有没有办法提高效率?
【问题讨论】:
-
这是一个 C++ 问题吗?
-
它与 SSE / C+ 相关 :) Array = __m256
-
在 SSE 中获取掩码是微不足道的。打包不是...
-
是的,上面的算法在 8 次昂贵的计算中进行了压缩:(尽管它不会分支或索引到 __m256。
-
我们允许使用哪些版本的 SSE?数组是什么类型? (我希望是字节)