altivec 提取向量的一部分?

Posted

技术标签:

【中文标题】altivec 提取向量的一部分?【英文标题】:altivec extract part of the vector? 【发布时间】:2013-09-16 21:55:01 【问题描述】:

我正在尝试将一个 64 位值与一个 64 位值数组进行比较,比如说

R_UINT64 FP; R_UINT64 输入[20000];

如果数组中的任何元素与 FP 的值匹配,则返回 true。

我必须遍历这个数组并找到一个匹配项,我试图通过一次查看 2 个元素而不是一个元素来提高效率。

在 Altivec 中,向量长度为​​ 128 位,因此我将 FP 的两个副本放入向量中。(我将它们都截断两个 8 位每个向量元素)

到目前为止一切顺利,但现在我遇到了问题。我找不到只查看一半向量并查看是否匹配的 VMX 过程,为了返回 true,两个值都必须匹配,这不是我想要的。

所以我想知道是否有办法告诉编译器我每次只查看一半向量?

提前致谢!

【问题讨论】:

【参考方案1】:

可能最好的办法是比较两个元素,然后使用vec_mergeh/vec_mergel 测试结果的每一半,例如

size_t vec_search_u64(const uint64_t key, const uint64_t array[], const size_t len)

    const vector signed int vkey =  key >> 32, key & 0xffffffff, key >> 32, key & 0xffffffff ;
    const vector bool int vk1 =  -1, -1, -1, -1 ;

    for (i = 0; i < len - 1; i += 2)      // iterate two elements at a time
    
        vector signed int v = vec_ld(0, (int *)&array[i]);
                                          // load 2 elements
        vector bool int vcmp = vec_cmpeq(v, vkey);
                                          // compare 2 elements with key
        if (vec_all_eq(vec_mergeh(vcmp, vcmp), vk1))
                                         // if high element matches
            return i;                     // return match found at element i 
        
        if (vec_all_eq(vec_mergel(vcmp, vcmp), vk1))
                                         // if low element matches
            return i + 1;                 // return match found at element i + 1
        
    
    if (i < len)                          // if array size is odd
    
        if (array[i] == key)              // test last element
        
            return i;
        
    
    return (size_t)(-1);                      // match not found - return suitable value

(注意:未经测试的代码 - 仅供一般指导 - 可能需要强制转换和/或实际的错误修复!)

【讨论】:

请注意,如果您运行的是 64 位 POWER 或 PowerPC,这可能不会比直接与 64 位寄存器进行简单的标量比较快多少,但如果您需要适度的性能,则值得一试改进。 嗨,保罗,最初的问题不允许我在大规模并行编程中实现。我想知道......无论如何,有没有一次将值加载到向量上?说 32 位,我可以一次加载一个 32 位 int 而不是一次加载 4 个吗?谢谢! 抱歉 - 我不太明白你的意思 - 只将一个值加载到向量中的意义何在?如果您只想一次比较一个元素,为什么不进行普通的标量比较? hmmm 不,我想一次加载一个的原因是值的计算是顺序的。所以情况就像一个累加器(比如 sum),sum+=(一个值),并且当 sum 等于参考值(比如 ref)时计算停止我正在考虑在一次迭代中将 4 sum 计算到一个向量上for 循环并将它们与 4 个 ref 副本的向量进行比较。不过,我不确定这是否会给我带来任何好处,因为我必须在之后检查哪一个匹配......但我想尝试并没有什么坏处 我建议现在只在简单的标量代码中实现这一点,并且仅在您已经分析了性能并且确定需要优化它时才考虑使用 SIMD。

以上是关于altivec 提取向量的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

matlab对矩阵/向量的常用操作(拼接矩阵向量逆序改变矩阵形状求行阶梯形矩阵提取矩阵的一部分等)

matlab对矩阵/向量的常用操作(拼接矩阵向量逆序改变矩阵形状求行阶梯形矩阵提取矩阵的一部分等)

如何使用 Altivec 将向量存储到内存中未对齐的位置

MATLAB如何提取某一矩阵中某一列的部分数据?

提取向量的向量子集

维度规约(特征的提取和组合)