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

标签 c operating-system pthreads cpu-architecture multicore

我有一个 C 程序,它创建两个线程(main 除外),T1T2。 T1 执行一个发出操作 O1 的函数,T2 执行一个发出操作 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 = %d\n", var);

    return 0;
}

t1t2 分别分配给不同的物理内核。该程序的目标是在两个线程完成执行后通过检查 var 的值来检查哪个操作更快。这将要求 O1() 和 O2() 在两个内核上同时运行(或者在几个周期的数量级上存在非常微小的可容忍差异)。我怎样才能确保这一点?

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

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

但是,t2 在控制台上打印的时间远远晚于 t1 的打印时间。我猜这表明 rdtsc 已在 f2() 中循环到 0,并且不会导致 O1() 的同步执行和O2()。线程屏障没有提供我需要的同步粒度。

最佳答案

在大多数平台上,

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

关于c - 在多个内核上同时运行两个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73094163/

相关文章:

C++ pthreads/semaphores 不运行

选择 pthread 中的打印顺序

c - printf 十六进制格式的 float 返回随机值

c - 生成随机 ASCII

objective-c - 语法: 'somestring' in Objective-C?的变量类型是什么

C++大内存分配

c++ - 如何在正则表达式中匹配 '*'

PHP:比较 NULL 和 FALSE - 转换为 ~Negative Infinity

c 中的自定义内存分配器

c - linux 线程和 fopen() fclose() fgets()