Cython 并行 prange - 线程局部性?

2024-01-23

我正在使用 prange 迭代这样的列表:

from cython.parallel import  prange, threadid

cdef int tid
cdef CythonElement tEl
cdef int a, b, c

# elList: python list of CythonElement instances is passed via function call
for n in prange(nElements, schedule='dynamic', nogil=True):
    with gil:
        tEl = elList[n]
        tid =  threadid()
        a = tEl.a
        b = tEl.b
        c = tEl.c 

        print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

   #nothing is done here

    with gil:
        print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

    # some other computations based on a, b and c here ...

我期望这样的输出:

thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4
thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4

但我得到:

thread 1 elnumber 1
thread 0 elnumber 3
thread 3 elnumber 2
thread 2 elnumber 4
thread 3 elnumber 4
thread 1 elnumber 2
thread 0 elnumber 4
thread 2 elnumber 4

那么,线程局部变量 tEl 会以某种方式在线程中被覆盖吗?我究竟做错了什么 ?谢谢你!


看起来 Cython 故意选择排除任何 Python 变量(包括 Cythoncdef classes) 来自线程局部变量列表。Code https://github.com/cython/cython/blob/c492bab673fe7869d33149358ba184e7b4f01536/Cython/Compiler/Nodes.py#L8288

我怀疑这是故意避免引用计数问题 - 他们需要在循环结束时删除所有线程局部变量的引用计数(这不会是一个不可克服的问题,但可能是一个很大的变化) 。因此我认为它不太可能被修复,但文档更新可能会有所帮助。

解决方案是将循环体重构为一个函数,其中每个变量最终都有效地“本地”到函数中,这样就不会出现问题:

cdef f(CythonElement tEl):
    cdef int tid
    with nogil:
        tid = threadid()
        with gil:
            print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

        with gil:
            print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

   # I've trimmed the function a bit for the sake of being testable

# then for the loop:
for n in prange(nElements, schedule='dynamic', nogil=True):
    with gil:
        f()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cython 并行 prange - 线程局部性? 的相关文章

  • 理解 JavaScript 的单线程本质

    我一直在阅读 John Resig 的 JavaScript Ninja 的秘密 它解释了 JavaScript 是单线程的 但是 我尝试对此进行测试 但我不确定要从这里删除什么 executing this in browser func
  • OpenMP:无法并行化嵌套 for 循环

    我想将循环与其中的内循环并行化 我的代码如下所示 pragma omp parallel for private jb ib shared n Nb lb lastBlock jj W WT schedule dynamic private
  • 使用 boost::thread 特定的 ptr<>::get() 是否会很慢?有什么解决方法吗?

    我目前正在使用 Valgrind 的 Callgrind 分析一个存在性能问题的应用程序 在查看分析数据时 似乎有 25 的处理时间花费在boost detail get tss data在主要目的是物理模拟和可视化的应用程序中 get t
  • 通过推送通知唤醒

    Suppose 有一些对象 例如 一个数组a 和依赖于对象的条件 例如 a empty 当前线程以外的某些线程可以操作该对象 a 因此条件评估值的真实性会随着时间的推移而变化 如何让当前线程在代码中的某个时刻休眠 并在条件满足时通过推送通知
  • 除非在后台线程中获取新的引用,否则存在潜在的引用计数问题

    我有一个second https stackoverflow com questions 28898966 prefer property accessor or kvc style for accessing core data prop
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 终结器线程的范围是什么 - 每个应用程序域或每个进程?

    根据我的所有阅读 应该有一个 GC 线程来调用所有终结器 现在的问题是这个 一个 线程的范围是什么 每个进程或每个应用程序域 因为域的整体目的是在一个进程空间中分离并创建 独立 的不同应用程序 I read here http dn cod
  • C# WinForms:使用一个或多个附加线程进行绘图。如何?

    如果我有一张包含各种几何形式 直线 矩形 圆形等 的大图 线程需要花费大量时间来绘制所有内容 但在现实生活中 一栋建筑是由不止一名工人建造的 因此 如果绘图是建筑物而线程是构建者 则绘制速度会快得多 但我想知道怎么做 你能告诉我怎么做吗 有
  • 使用 Cythonized Python Wheels 指定精确的 CPU 指令集

    我有一个带有本机扩展的 Python 包 由Cython https cython org 由于一些性能需要 编译是用 march native mtune native旗帜 这基本上使编译器能够使用任何可用的 ISA 扩展 此外 我们保留
  • 调试 Java InterruptedException,即查找原因

    在调试Android应用程序时 有时中断异常发生并使应用程序崩溃 我已经能够在默认异常处理程序上设置断点 但调用堆栈不提供信息 at java util concurrent locks AbstractQueuedSynchronizer
  • 这个等待通知线程语义的真正目的是什么?

    我刚刚遇到一些代码 它使用等待通知构造通过其其他成员方法与类中定义的线程进行通信 有趣的是 获取锁后 同步范围内的所有线程都会在同一锁上进行定时等待 请参见下面的代码片段 随后 在非同步作用域中 线程执行其关键函数 即 做一些有用的事情1
  • PyQt5:如何使QThread返回数据到主线程

    I am a PyQt 5 4 1 1初学者 我的Python是3 4 3 这是我尝试遵循的many https mayaposch wordpress com 2011 11 01 how to really truly use qthr
  • 当客户端关闭连接时,Spring StreamingResponseBody 请求线程未清理

    我在控制器中有一个端点 它返回一个StreamingResponseBody 用于向客户端发送文件 其代码大致如下 RestController RequestMapping value api public class Controlle
  • VB - 以隐式方式链接 DLL

    我正在开发 VB6 图形界面 并且需要隐式链接到 DLL 这样做的动机来自于我上一个问题 https stackoverflow com questions 5194573 有问题的 DLL 使用静态 TLS declspec thread
  • Android:如何使用后台线程?

    我开发了一个应用程序 它从互联网获取内容并相应地在设备的屏幕上显示它 该程序运行得很好 就是有点慢 加载并显示内容大约需要 3 4 秒 我想将获取内容并将其显示在后台线程中的所有代码放在一起 当程序执行这些功能时 我想显示一个进度对话框 你
  • 异步迭代器

    我有以下代码 while slowIterator hasNext performLengthTask slowIterator next 由于迭代器和任务都很慢 因此将它们放入单独的线程中是有意义的 这是对迭代器包装器的快速而肮脏的尝试
  • 线程睡眠和Windows服务

    我正在开发一个 Windows 服务 该服务存在一些问题Thread Sleep 所以我想我会尝试使用计时器 因为这个问题建议 在 Windows 服务中使用 Thread Sleep https stackoverflow com que
  • 同时调用多个 API,并在相应请求处理完成后立即更新 UI Android

    我需要跑6个API同时调用并且需要在相应的请求完成时更新每个用户界面 目前我正在使用kotlin 协程并行执行使用以下代码 suspend fun getAllData List
  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • 异步多播委托

    我最近在一个广泛使用事件的项目上做了一些工作 我需要做的事情之一是在多播委托上异步调用多个事件处理程序 我认为诀窍是对 GetInvocableList 中的每个项目调用 BeginInvoke 但似乎那里不存在 BeginInvoke 有

随机推荐