Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么并行化版本比单线程版本慢。虚假分享?_C++_Multithreading_Parallel Processing_Process - Fatal编程技术网

C++ 为什么并行化版本比单线程版本慢。虚假分享?

C++ 为什么并行化版本比单线程版本慢。虚假分享?,c++,multithreading,parallel-processing,process,C++,Multithreading,Parallel Processing,Process,下面是代码的两个版本: class VectorCount { private: char *arr;int size;unsigned long long count; public: VectorCount(char *arr, unsigned int size, unsigned long long count) : arr(arr), size(size), count(count) {}

下面是代码的两个版本:

class VectorCount {
private:
     char               *arr;int                
     size;unsigned long long count;
public:
     VectorCount(char *arr, unsigned int size, unsigned long long count) : arr(arr), size(size), count(count) {}

     void add() {
          while(count--) {
               for (int i = 0; i < size; i++) {
                         arr[i]++;
               }
          }
     }
};

// Single-thread version of the code
void main_st() {
     // initizalize array
     char arr[10];

     // create object
     VectorCount v(arr, 10, 100000000);

     // run add
     v.add();
}

// Parallelized version of the code
void main_mt() {
     // initialize array
     char arrA[10];
     char arrB[10];

     // create objects
     VectorCount v1(arrA, 10, 50000000);
     VectorCount v2(arrB, 10, 50000000);

     // create threads
     thread t1, t2;
     t1.create_thread(v1, v1.add);
     t2.create_thread(v2, v2.add);

     // join threads
     t1.join();
     t2.join();

     // Code to do the final sum of the two VectorCount objects to get the same
     // result as the single-threaded version (assume negligible overhead here)
}
类向量计数{
私人:
字符*arr;int
大小;无符号长计数;
公众:
向量计数(char*arr,unsigned int size,unsigned long long count):arr(arr),size(size),count(count){
void add(){
而(计数--){
对于(int i=0;i
假设程序创建了一个数组大小为10、计数为1亿的VectorCount对象实例。单线程版本需要5秒来完成总和。并行化版本使用两个线程,每个线程分别持有一个数组大小为10的VectorCount实例,因此每个VectorCount实例的计数仅为5000万,因为每个线程完成了一半的工作。并行化版本需要8秒钟才能完成。为什么会慢一些?我想这是因为虚假的分享。但我不确定。缓存大小为64字节

我们能让并行版本运行得更快吗?我正在考虑更改向量计数数组大小。但是,使用2个线程时,多大的大小会使并行化版本运行得更快呢?既然缓存大小是64字节,int是4字节,那么size=16能解决这种情况下的错误共享吗?(4 x 16=64)


谢谢您的帮助。

您的代码只做了很少的工作,只要有足够的上下文,优化人员就可以将您的代码转换为基本的内容(假设与您的情况一样,
count
可以被
size
整除):

使它更类似于您的单线程版本,并且Optimizer能够执行其神奇功能,而并行版本的速度要快得多:。如果您查看第一个版本的汇编代码,您会注意到其中提到了
50000000
,但没有提到
100000000
,在第二个版本中,您会注意到
50000000
也没有,因为两个版本都没有优化

请注意,它仍然比单线程版本慢,但由于单线程版本只需要约100ns的时间,因此创建和连接两个线程的开销可能比从并行性中节省的开销要大

在我使用visual studio的机器上,单线程版本的代码需要85毫秒,并行版本的代码需要45毫秒(visual studio无法完全删除代码)


阻塞Optimizer会在GCC上给出更相似的结果:

最好有一个可复制的示例。更好的利用甚至还有一些可能性:首先,它可能是两个线程调度在同一个内核上,这比单线程慢。第二,每次在不同的内核上安排两个线程版本,这会导致旧内核中的刷新缓存和当前内核中的未命中缓存。您的代码做得很少,并且可能会被编译器优化,创建线程可能比您的代码可能归结为的10个赋值花费更长的时间,如果您的代码没有得到优化,那么任何性能度量都是没有意义的,即
t1
t2
std::thread
s?我似乎找不到任何名为
create\u thread
的成员函数。
for (int i = 0; i < size; i++) {
  arr[i] = count / size;
}
std::thread t1([] {
    char arrA[10]{0};
    VectorCount v1(arrA, 10, 50'000'000);
    v1.add();
    });
std::thread t2([] {
    char arrA[10]{0};
    VectorCount v1(arrA, 10, 50'000'000);
    v1.add();
    }
);