C++ C++;线程性能

C++ C++;线程性能,c++,arrays,multithreading,performance,C++,Arrays,Multithreading,Performance,我制作了一个小程序来观察使用两个线程的速度。我正在为填充数组的过程计时。A主线程和thread1调用函数_1来初始化数组的不同半部分。我希望通过使用两个线程可以看到更快的结果。相反,我的时间变慢了,注释掉的代码执行得更快。这件事我哪里做错了 #include <chrono> #include <iostream> #include <vector> #include <thread> void function_1(int I, int J,

我制作了一个小程序来观察使用两个线程的速度。我正在为填充数组的过程计时。A主线程和thread1调用函数_1来初始化数组的不同半部分。我希望通过使用两个线程可以看到更快的结果。相反,我的时间变慢了,注释掉的代码执行得更快。这件事我哪里做错了

#include <chrono>
#include <iostream>
#include <vector>
#include <thread>


void function_1(int I, int J, int *B){
    for (int i = I; i<(J+1); i++) {
        B[i] = 100;
       //std::cout << B[i] << std::endl;
    }
}

int *count;

int main(int argc, const char * argv[])
{
    count = new int[20000];

    std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
    //function_1(0, 19999, count);
    std::thread thread1(function_1, 0, 9999, count);
    thread1.join();
    function_1(10000, 19999, count);

    std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
    auto time_span = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
    std::cout << "time taken is :" <<time_span << " ms"<<std::endl;

    return 0;
}
#包括
#包括
#包括
#包括
空洞函数_1(int I,int J,int*B){

对于(int i=i;i您正在同步执行示例代码,方法是在创建后立即加入thread1。main()中的执行将被阻止,直到该线程终止处理,然后移动到
函数_1(10000,19999,count)
为了利用额外的线程,请尝试在调用main中的
函数_1(10000,19999,count);
之后移动连接调用。

您正在同步执行示例代码,方法是在创建thread1后立即连接它。main()中的执行将阻塞,直到该线程终止处理,然后移动到
函数_1(10000,19999,计数);
为了利用额外的线程,请尝试在调用main中的
函数_1(10000,19999,计数);
之后移动连接调用

std::thread thread1(function_1, 0, 9999, count);
thread1.join();
function_1(10000, 19999, count);
主线程将等待
thread1
完成工作,然后再调用
函数_1
。这与调用相同

function_1(...)
function_1(...)
在主线程上,仅使用管理线程带来的额外成本。在主线程上调用
函数_1
后,您可能需要
join()

此外,你应该增加工作量以使测试更加相关。线程不是一种无代价的快速完成工作的方法。在决定线程是否与你的情况相关之前,你需要考虑维护线程的成本。 主线程将等待

thread1
完成工作,然后再调用
函数_1
。这与调用相同

function_1(...)
function_1(...)
在主线程上,仅使用管理线程带来的额外成本。在主线程上调用
函数_1
后,您可能需要
join()


此外,你应该增加工作量以使测试更加相关。线程并不是一种无代价的快速完成工作的方法。在决定线程是否与你的情况相关之前,你需要考虑维护线程的成本。

当手头的任务只包括填充时,你不太可能看到一个大的改进。记忆

问题很简单:一个内核可能会占用内存的全部带宽。在这种情况下,添加更多线程不会有多大好处,除非您的计算机具有多个处理器,而不仅仅是单个插槽中的多个内核

使用多个套接字,您可以通过在单独的物理处理器上运行不同的线程来提高速度,每个线程都有自己的内存连接。但是,为了使这一点有效,您通常需要使用一些非标准函数调用来确保每个线程在单独的物理处理器上运行,并确保线程在每个处理器上运行会写入该处理器本地的内存

这两个都不完全是火箭科学,但它们也不一定是微不足道的。即使是最简单的,至少有一部分代码几乎肯定是不可移植的


要想从多个线程中获得主要收益,您通常需要执行包含各种不同类型工作的混合任务:例如,一些是I/O限制的,一些是内存限制的,一些是处理器限制的。在这种情况下,从多个线程中获得大幅度的加速要容易得多。如果您不能做到这一点,那么这可能是第二种选择,因为处理器受到严重限制。假设线程之间的同步很少或不同步,那么很有可能获得大致线性的加速(即,N个内核执行代码的速度大约是一个内核的N倍).

当手头的任务只包括填充内存时,您不太可能看到重大改进

问题很简单:一个内核可能会占用内存的全部带宽。在这种情况下,添加更多线程不会有多大好处,除非您的计算机具有多个处理器,而不仅仅是单个插槽中的多个内核

使用多个套接字,您可以通过在单独的物理处理器上运行不同的线程来提高速度,每个线程都有自己的内存连接。但是,为了使这一点有效,您通常需要使用一些非标准函数调用来确保每个线程在单独的物理处理器上运行,并确保线程在每个处理器上运行会写入该处理器本地的内存

这两个都不完全是火箭科学,但它们也不一定是微不足道的。即使是最简单的,至少有一部分代码几乎肯定是不可移植的


要想从多个线程中获得主要收益,您通常需要执行包含各种不同类型工作的混合任务:例如,一些是I/O限制的,一些是内存限制的,一些是处理器限制的。在这种情况下,从多个线程中获得大幅度的加速要容易得多。如果您不能做到这一点,那么这可能是第二种选择。假设线程之间的同步很少或不同步就可以做到这一点,那么很有可能获得大致线性的加速(即,N个内核执行代码的速度大约是一个内核的N倍)。

我移动了thread1.join()在main调用函数_1之后。由于某些原因,使用两个线程仍然比使用一个带有注释掉的代码的线程慢。测试似乎有点太琐碎。线程管理很可能会对性能产生负面影响。线程并不是真正免费的