读取共享变量的线程首先调用flush
,写入共享变量的线程之后必须调用OpenMP flush
,以便将共享变量保存在主内存和缓存中同步。 flush
函数如何知道要刷新的方向?它需要知道哪个变量(主存储器或缓存)更新。我假设,但我不确定,操作系统或CPU以某种方式处理这个问题。有人知道吗?
答案 0 :(得分:1)
flush
不是函数 - 它是OpenMP 编译器指令。它会影响编译器生成可执行代码的方式,并指示它在flush-set中同步所有优化变量(存储在CPU寄存器或其他显式可编程缓存/线程本地内存中)的值。这类似于volatile
存储修饰符对代码生成的影响,但具有更有限的点局部效应。
它是如何工作的?在解析源代码时,编译器会分析语句流和受这些语句影响的数据(变量)。因此,编译器根据代码构建执行图和数据依赖图。它确切地知道每个变量的值的使用位置和方式以及执行哪个代码块会影响哪些变量。然后,编译器尝试通过简化图形来优化代码,并通过使用CPU寄存器来存储中间值或通过使用另一个来获得更快的线程可寻址本地存储器来减少昂贵的存储器操作的数量。 flush
指令在执行图中添加了特殊点,其中编译器必须显式地将线程的内存视图(寄存器变量和本地内存变量)与全局共享内存同步。由于编译器首先构建了依赖图,因此它确切地知道刷新集中的哪些变量被修改,因此必须写入共享内存;必须从共享内存中读取flush-set中的所有其他变量。
所以你的问题的答案是,通常编译器会处理flush
指令,而不是操作系统,尽管编译器可能会调用操作系统来实际执行刷新,例如,在具有显式可编程高速缓存/本地存储器的系统上但是还应该注意OpenMP是一个抽象标准,它可以在许多不同的硬件平台上实现,并且其中一些平台提供某些硬件可以帮助更有效地实现OpenMP抽象(例如IBM的Blue Gene / Q中的CPU ASIC提供了许多这样的功能。)
答案 1 :(得分:-1)
您不需要调用flush来保持共享变量同步。 硬件(CPU)会跟踪缓存的内存,如果存在冲突的访问,它们会降低程序的速度,因为缓存将被CPU刷新。
我理解flush指令更像是conditional barrier。 必须至少有两个线程遇到包含相同变量的flush以产生效果。 如果两个线程共同使用变量a,那么如果它们已经修改了它,那么它们会将它们的修改写回到内存中(而不是将它保存在局部变量或寄存器中),并且那么我想两个线程都有障碍在它们继续之前到达那个点。 如果在刷新后使用变量a,则从内存中重新读取它。