将几个std :: vectors复制到1的更好方法是什么? (多线程)

时间:2010-07-07 03:37:08

标签: c++ multithreading vector

以下是我正在做的事情:

我正在接受贝塞尔点并运行贝塞尔插值,然后将结果存储在std::vector<std::vector<POINT>.

bezier计算让我放慢了速度,所以这就是我所做的。

我从一个std::vector<USERPOINT>开始,这是一个带有一个点的结构和另外两个用于贝塞尔手柄的点。

我把这些分成~4组,并指定每个线程完成1/4的工作。为此,我创建了4 std::vector<std::vector<POINT> >来存储每个线程的结果。最后所有的点都必须在1个连续向量中,在我使用多线程之前我直接访问它但现在我保留了4的大小由线程生成的向量,并以正确的顺序将它们插入到原始向量中。这很有效,但不幸的是,复制部分非常慢,并且比没有多线程的速度慢。所以现在我的新瓶颈是将结果复制到矢量。我怎么能更有效地这样做?

由于

3 个答案:

答案 0 :(得分:4)

让所有线程将结果放入一个连续的向量中,就像之前一样。您必须确保每个线程仅访问与其他线程分开的向量部分。只要是这种情况(它应该是无论如何 - 你不想生成两次相同的输出),每个仍然使用与其他存储器分开的存储器,并且你不需要任何锁定(等等)为了工作。但是,您确实需要/想要确保结果的向量首先具有所有结果的正确大小 - 多个线程尝试(例如)在向量上调用resize()push_back() 匆忙造成严重破坏(更不用说导致复制了,你明显要避免这种情况)。

编辑:正如Billy O'Neal指出的那样,通常的方法是将指针传递给向量的每个部分,每个部分将存放其输出。为了论证,让我们假设我们使用提到的std::vector<std::vector<POINT> >作为事物的原始版本。目前,我将跳过创建线程的细节(特别是因为它因系统而异)。为简单起见,我还假设要生成的曲线数量是线程数的精确倍数 - 实际上,曲线不会完全均匀地划分,因此您必须“捏造”算一个线程,但这与手头的问题无关。

std::vector<USERPOINT> inputs; // input data   
std::vector<std::vector<POINT> > outputs; // space for output data

const int thread_count = 4;

struct work_packet {           // describe the work for one thread
    USERPOINT *inputs;         // where to get its input
    std::vector<POINT> *outputs;   // where to put its output
    int num_points;                // how many points to process
    HANDLE finished;               // signal when it's done.
};

std::vector<work_packet> packets(thread_count); // storage for the packets.
std::vector<HANDLE> events(thread_count);       // storage for parent's handle to events

outputs.resize(inputs.size);                    // can't resize output after processing starts.

for (int i=0; i<thread_count; i++) {
    int offset = i * inputs.size() / thread_count;
    packets[i].inputs = &inputs[0]+offset;
    packets[i].outputs = &outputs[0]+offset;
    packets[i].count = inputs.size()/thread_count;
    events[i] = packets[i].done = CreateEvent();

    threads[i].process(&packets[i]);
}


// wait for curves to be generated (Win32 style, for the moment).
WaitForMultipleObjects(&events[0], thread_count, WAIT_ALL, INFINITE);

请注意,虽然我们必须确保outputs向量在多个线程操作时不会调整大小,但输出中的点的各个向量可以是的,因为每次只能被一个线程触及。

答案 1 :(得分:0)

如果事物之间的简单复制比开始使用多线程之前的速度慢,那么你所做的事情很可能不会扩展到多个核心。如果它像bezier的东西一样简单,我怀疑情况会如此。

请记住,制作线程等的开销会对总运行时间产生影响。

最后..对于副本,你在用什么?是std::copy吗?

答案 2 :(得分:-1)

多线程不会加快你的进程。处理不同核心的数据,可以。