如何矢量化此程序

how to vectorize this program

本文关键字:程序 矢量化      更新时间:2023-10-16
下面的

程序(好吧,"从这里"后面的行)是我必须经常使用的结构。我想知道这是否可能(最终使用特征库中的函数)矢量化或以其他方式使该程序运行得更快。

本质上,给定一个float x向量,这个构造已经恢复了索引int向量中x的排序元素SIndex .例如,如果第一个SIndex的条目是 10,这意味着x的第 10 个元素是最小的元素的x .

#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
using std::vector;
using namespace std;
typedef pair<int, float> sortData;
bool sortDataLess(const sortData& left, const sortData& right){
    return left.second<right.second;
}
int main(){
    int n=20,i;
    float LO=-1.0,HI=1.0;
    srand (time(NULL));
    vector<float> x(n);
    vector<float> y(n);
    vector<int> SIndex(n);  
    vector<sortData> foo(n);
    for(i=0;i<n;i++) x[i]=LO+(float)rand()/((float)RAND_MAX/(HI-LO));
    //from here:
    for(i=0;i<n;i++) foo[i]=sortData(i,x[i]);
    sort(foo.begin(),foo.end(),sortDataLess);
    for(i=0;i<n;i++){
        sortData bar=foo[i];
        y[i]=x[bar.first];
        SIndex[i]=bar.first;
    }
    for(i=0;i<n;i++) std::cout << SIndex[i] << std::endl;
    return 0;
}
无法

回避这是一个排序问题,矢量化不一定能很好地改善排序。例如,快速排序的分区步骤可以并行进行比较,但它随后需要选择并存储通过比较的 0–n 值。这绝对可以做到,但它开始抛弃你从矢量化中获得的优势——你需要从比较掩码转换为随机掩码,这可能是一个查找表(不好),你需要一个可变大小的存储,这意味着没有对齐(不好,尽管可能不是那么糟糕)。Mergesort 需要合并两个排序列表,在某些情况下可以通过矢量化来改进,但在最坏的情况下(我认为)需要与标量情况相同的步骤数。

而且,当然,您从矢量化中获得的任何重大速度提升很有可能已经在标准库的std::sort实现中完成。但是,要获得它,您需要使用默认的比较运算符对基元类型进行排序。

不过,如果您担心性能,可以轻松避免最后一个循环。只需使用浮点数组作为比较对索引列表进行排序:

struct IndirectLess {
    template <typename T>
    IndirectLess(T iter) : values(&*iter) {}
    bool operator()(int left, int right)
    {
        return values[left] < values[right];
    }
    float const* values;
};
int main() {
    // ...
    std::vector<int> SIndex;
    SIndex.reserve(n);
    for (int i = 0; i < n; ++i)
        SIndex.push_back(n);
    std::sort(SIndex.begin(), SIndex.end(), IndirectLess(x.begin()));
    // ...
}

现在,您生成了排序索引的列表。您可能会丢失一些缓存位置,因此对于非常大的列表,它可能会更慢。此时,可以根据体系结构对最后一个循环进行矢量化处理。不过,这只是数据操作——读取四个值,将第 1 和第 3 个存储在一个地方,将第 2 和第 4 个存储在另一个地方——所以我不希望 Eigen 在这一点上提供多大帮助。