c-在多个核心上同时运行两个函数



我有一个C程序,它创建两个线程(除了main(,T1T2。T1执行发出操作O1的功能,T2执行发出操作〈em>O2

void* f1() {
    O1();
    var = 0;
}
void* f2() {
    O2();
    var = 1;
}
int main(int argc, char **argv){
    pthread_t t1, t2;
    int var;
    pthread_create(&t1, NULL, &f1, NULL);
    pthread_create(&t2, NULL, &f2, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("var = %dn", var);
    return 0;
}

CCD_ 1和CCD_。该程序的目的是在两个线程都完成执行后,通过检查var的值来检查哪个操作更快。这将要求O1((和O2((在两个核心上同时并行运行(或者以几个周期的数量级存在非常轻微的可容忍差异(。我该如何确保这一点?

编辑:根据Peter Cordes的建议,我修改了f1()f2(),以读取O1()O2()同步执行的时间戳。

void* f1() {
    t1 = rdtsc();
    while(t1 != 0){
        t1 = rdtsc();
    }   
    printf("t1 = %dn", t1);
    O1();
    var = 0;
}
void* f2() {
    t2 = rdtsc();
    while(t2 != 0){
        t2 = rdtsc();
    }   
    printf("t2 = %dn", t2);
    O2();
    var = 1;
}

然而,t2在控制台上打印的时间远远晚于t1。我想这表明t10已经在f2()中循环到0,并且没有导致O1()O2()的同步执行。线程屏障没有提供我所要求的同步粒度。

f1f2在大多数平台上的实际调用中肯定会有很小的延迟,但延迟取决于硬件、操作系统(OS(,尤其是其调度程序。从理论上讲,不可能保证这两个功能在所有平台上总是同时启动。事实上,操作系统调度器可以自由地调度同一核心上的线程,即使您将线程绑定到核心,线程也可以随时中断(例如,由更高优先级的任务中断(。此外,在大多数现代处理器上,核心时钟并不强同步。也就是说,在实践中,屏障显然足以使函数大致同时运行(在大多数系统上,粒度接近几微秒,甚至更少(。Pthread提供了这样的特性(例如,请参见pthread_barrier_initpthread_barrier_wait(。请注意,可能需要旋转等待以获得更好的精度(通常为1-10ns,可能与硬件有关(。AFAIK不可能以比x86处理器几十个周期更好的精度同步线程。这是因为现代处理器以并行和无序的方式运行指令,具有相当长的复杂管道,并且任何核心间同步都特别慢(通常是因为要走的路径很长、缓存一致性协议和基本物理定律(。

确定O1((或O2((是否更快的最准确方法是对每种方法进行基准测试。有非常准确的方法可以测量运行时间,当然,运行O1((几次,然后运行O2((几遍,并记录启动/停止时间,会给出准确的平均答案。平均值中包含的运行次数越多,结果就越准确,结果的标准偏差也就越确定。

依靠操作系统以某种方式即时启动线程并不是很好。无法保证操作系统在第一个线程启动后会运行main((;有些操作系统会让新创建的线程运行一段时间,而不是它的创建线程,只是为了看看它是否能快速完成(有些确实如此(。

相关内容

  • 没有找到相关文章

最新更新