C 扩展中 IO 有界线程的 GIL (HDF5)

2024-03-02

我有一个采样应用程序,它获取250,000每秒采样,将它们缓冲在内存中并最终附加到HDFStore由...提供pandas。总的来说,这很棒。但是,我有一个线程运行并不断清空数据采集设备(DAQ)并且它需要定期运行。大约一秒的偏差往往会破坏东西。以下是观察到的时间的极端情况。Start表示一个DAQ读开始,Finish是当它完成时,并且IO表示 HDF 写入(两者DAQ and IO发生在单独的线程中)。

Start        : 2016-04-07 12:28:22.241303
IO (1)       : 2016-04-07 12:28:22.241303
Finish       : 2016-04-07 12:28:46.573440 (0.16 Hz, 24331.26 ms)
IO Done (1)  : 2016-04-07 12:28:46.573440 (24332.39 ms)

正如您所看到的,执行此写入需要 24 秒(典型写入约为 40 毫秒)。我正在写入的 HDD 没有负载,因此这种延迟不应由争用引起(运行时利用率约为 7%)。我已禁用索引HDFStore写道。我的应用程序运行许多其他线程,所有这些线程都打印状态字符串,因此 IO 任务似乎正在阻塞所有其他线程。我花了相当多的时间逐步浏览代码来找出速度变慢的地方,并且它总是在 C 扩展提供的方法内,这引出了我的问题..

  1. Python(我使用的是 3.5)可以抢占 C 扩展中的执行吗?并发性:用 C/C++ 编写的 Python 扩展是否受到全局解释器锁的影响? https://stackoverflow.com/questions/651048/concurrency-are-python-extensions-written-in-c-c-affected-by-the-global-inter似乎表明除非扩展明确产生,否则不会。
  2. Pandas 的 HDF5 C 代码是否实现了 I/O 的任何让步?如果是这样,这是否意味着延迟是由于 CPU 受限任务造成的?我已禁用索引。
  3. 关于如何获得一致的时间安排有什么建议吗?我正在考虑将 HDF5 代码移至另一个进程中。不过,这只在一定程度上有帮助,因为无论如何我都无法真正容忍大约 20 秒的写入,尤其是当它们不可预测时。

您可以运行以下示例来查看问题:

import pandas as pd
import numpy as np
from timeit import default_timer as timer
import datetime
import random
import threading
import time

def write_samples(store, samples, overwrite):
    frame = pd.DataFrame(samples, dtype='float64')

    if not overwrite:
        store.append("df", frame, format='table', index=False)
    else:
        store.put("df", frame, format='table', index=False)

def begin_io():
    store = pd.HDFStore("D:\\slow\\test" + str(random.randint(0,100)) + ".h5", mode='w', complevel=0)

    counter = 0
    while True:
        data = np.random.rand(50000, 1)
        start_time = timer()
        write_samples(store, data, counter == 0)
        end_time = timer()

        print("IO Done      : %s (%.2f ms, %d)" % (datetime.datetime.now(), (end_time - start_time) * 1000, counter))

        counter += 1

    store.close()

def dummy_thread():
    previous = timer()
    while True:
        now = timer()
        print("Dummy Thread  : %s (%d ms)" % (datetime.datetime.now(), (now - previous) * 1000))
        previous = now
        time.sleep(0.01)


if __name__ == '__main__':
    threading.Thread(target=dummy_thread).start()
    begin_io()

您将得到类似于以下内容的输出:

IO Done      : 2016-04-08 10:51:14.100479 (3.63 ms, 470)
Dummy Thread  : 2016-04-08 10:51:14.101484 (12 ms)
IO Done      : 2016-04-08 10:51:14.104475 (3.01 ms, 471)
Dummy Thread  : 2016-04-08 10:51:14.576640 (475 ms)
IO Done      : 2016-04-08 10:51:14.576640 (472.00 ms, 472)
Dummy Thread  : 2016-04-08 10:51:14.897756 (321 ms)
IO Done      : 2016-04-08 10:51:14.898782 (320.79 ms, 473)
IO Done      : 2016-04-08 10:51:14.901772 (3.29 ms, 474)
IO Done      : 2016-04-08 10:51:14.905773 (2.84 ms, 475)
IO Done      : 2016-04-08 10:51:14.908775 (2.96 ms, 476)
Dummy Thread  : 2016-04-08 10:51:14.909777 (11 ms)

答案是否定的,这些作者不会发布 GIL。查看文档here http://pandas.pydata.org/pandas-docs/stable/io.html#caveats。我知道你实际上并不是想用multiple线程,但这应该会提示您。当发生写入时,会持有强锁,以真正防止多次写入。两个都PyTables and h5py将此作为 HDF5 标准的一部分。

你可以看看SWMR http://docs.h5py.org/en/latest/swmr.html,尽管 pandas 不直接支持。PyTables docs here http://www.pytables.org/cookbook/threading.html and here http://www.pytables.org/FAQ.html#can-pytables-be-used-in-concurrent-access-scenarios指出解决方案。这些通常涉及使用单独的进程从队列中提取数据并将其写入。

无论如何,这通常是一种更具可扩展性的模式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 扩展中 IO 有界线程的 GIL (HDF5) 的相关文章

  • Flask/Apache 提交按钮用于文件上传

    我有一个在 apache 后面运行的 Flask 应用程序 在我的 index html 页面上有一个文件上传按钮和一个提交按钮 如下所示
  • pandas python 根据一个或多个其他列的子集更新 A 列的子集

    Edit我修改了下面的部分描述 以澄清 功能 和 组 的含义 修复拼写错误 并包含我尝试过的其他代码 我的熊猫df有 450 万行和 23 列 下表显示了几行df2这是从生成的df 它显示了两组 eeskin and hduquant 和三
  • 如何在 python 中使用 libSVM 计算精度、召回率和 F 分数

    我想计算precision recall and f score using libsvm在Python中 但我不知道如何 我已经发现这个网站 http www csie ntu edu tw cjlin libsvmtools eval
  • PyQt4 信号和槽

    我正在使用 PyQt4 编写我的第一个 Python 应用程序 我有一个 MainWindow 和一个 Dialog 类 它是 MainWindow 类的一部分 self loginDialog LoginDialog 我使用插槽和信号 这
  • 使用解析将 ** 运算符更改为幂函数?

    我的要求是将 运算符更改为幂函数 例如 1 Input B 2 Output power B 2 2 B 2 T 2 X Output power B 2 我写了下面的正则表达式来解决这个问题 rx r a zA Z0 9 a zA Z0
  • 创建一个行为类似于任何变量但具有更改/读取回调的类

    我想创建一个类 其行为类似于 python 变量 但在更改 读取 变量 时调用一些回调函数 换句话说 我希望能够按如下方式使用该类 x myClass change callback read callback 将 x 定义为 myclas
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 熊猫 style.background_gradient 忽略 NaN

    我有以下代码来转储数据帧results到 HTML 表格中 这样的列TIME FRAMES根据seaborn 的颜色图进行着色 import seaborn as sns TIME FRAMES 24h 7d 30d 1y Set CSS
  • 在 PyCharm 中运行命令行命令

    你好 我正在使用Python 但之前从未真正使用过它 我收到一些命令 需要在终端中运行 基本上 python Test py GET feeds 我正在使用 PyCharm 我想知道是否有办法从该 IDE 中运行这些相同的命令 按 Alt
  • Tensorflow 到 ONNX 的转换

    我目前正在尝试转换我使用本教程创建的已保存 且正在工作 的 pb 文件 https github com thtrieu darkflow https github com thtrieu darkflow 到 onnx 文件中 我目前正在
  • Pandas:向量化局部范围操作([i:i+2] 行的最大值和总和)

    我希望在数据帧中的每一行的局部范围内进行计算 同时避免速度缓慢for环形 例如 对于下面数据中的每一行 我想找到未来 3 天内 包括当天 的最高气温以及未来 3 天内的总降雨量 Day Temperature Rain 0 30 4 1 3
  • 使用 python 写入 aws lambda 中的 /tmp 目录

    Goal 我正在尝试将 zip 文件写入 python aws lambda 中的 tmp 文件夹 因此我可以在压缩之前提取操作 并将其放入 s3 存储桶中 Problem 操作系统 Errno30 只读文件系统 这段代码在我的计算机上进行
  • 计算二维笛卡尔坐标中不规则形状的边界

    我正在寻找一种计算不规则形状边界的解决方案 Lats take a look at Square example 如果我有Minimum x and y and Maximum x and y like MaxX 5 MinX 1 MaxY
  • 使用 Matplotlib、PyQt 和 Threading 进行实时绘图导致 python 崩溃

    我一直在努力研究我的 Python 应用程序 但找不到任何答案 我有 PyQT GUI 应用程序 它使用 Matplotlib 小部件 GUI 启动一个新线程来处理 mpl 小部件的绘图 恐怕我现在通过从另一个线程访问 matplotlib
  • wxPython:更新wx.ListBox列表

    我在 python 程序中有一个 wx ListBox 我不想在 wx Timer 更新时更改其中的列表 我的计时器正在工作 我只是不知道如何更改它显示的列表 这是一个例子 http www daniweb com code snippet
  • Python:如何使用生成器来避免 sql 内存问题

    我有以下方法来访问 mysql 数据库 并且查询在服务器中执行 我无权更改有关增加内存的任何内容 我对生成器很陌生 并开始阅读更多有关它的内容 并认为我可以将其转换为使用生成器 def getUNames self globalUserQu
  • 在 Django 中翻译文件时的 Git 命令

    我在 Django 中有一个现有的应用程序 我想在页面上添加翻译 在页面上我有 trans Projects 在 po 文件中我添加了 templates staff site html 200 msgid Projects msgid P
  • 有效积累稀疏 scipy 矩阵的集合

    我有一个 O N NxN 的集合scipy sparse csr matrix 每个稀疏矩阵都有 N 个元素集 我想将所有这些矩阵加在一起以获得一个常规的 NxN numpy 数组 N 约为 1000 矩阵内非零元素的排列使得所得总和肯定不
  • Scrapy - 持续从数据库中获取要爬取的url

    我想不断地从数据库中获取要爬行的网址 到目前为止 我成功地从基地获取了 url 但我希望我的蜘蛛继续从该基地读取 因为该表将由另一个线程填充 我有一个管道 一旦爬行 工作 就会从表中删除 url 换句话说 我想使用我的数据库作为队列 我尝试
  • Pymongo 批量插入

    我正在尝试批量插入文档 但批量插入时不会插入超过 84 个文档 给我这个错误 in insert pymongo errors InvalidOperation cannot do an empty bulk insert 是否可以批量插入

随机推荐

  • 如何忽略异常并完成尝试

    所以我一直在奋斗这个问题 https stackoverflow com questions 14885288 io exception error when using serialport open大约一周了 我想我知道这个问题 但我不
  • Twig 和自动转义

    我正在学习 Symfony2 目前 我正在尝试在树枝模板中渲染表单标签 该标签包含一个 html 标签 该标签在我的 twig 文件中未正确呈现 下面是创建表单字段的代码段 builder gt add zipcode integer ar
  • Avalon 中的大写编辑

    我正在使用 AvalonEdit 编写电影脚本编辑器 我扩展了 DocumentLine 类以具有 Type 属性 其值表示 字符 对话行 等 我希望脚本中某种类型的文档行以大写形式编写 例如字符名称 渲染管道中是否有一个扩展点可以让我获取
  • 如何在 zend Framework 2 中返回对象数组?

    我正在 zf2 中进行查询 然后得到一个object Zend Db ResultSet HydratingResultSet 我必须foreach上 以便到达属性 我想默认获得一个对象数组 这是我的一些代码 factory address
  • clang 不编译我的代码,但 g++ 可以

    有人可以帮我解决这个代码吗 include
  • NodeJS 中的 HTTPS 请求

    我正在尝试编写一个 NodeJS 应用程序 它将使用 https 包中的请求方法与 OpenShift REST API 进行通信 这是代码 var https require https var options host openshif
  • 使用 ggforce 创建跳过节点的 Sankey 图

    I would like to use the ggforce package in R to create a Sankey diagram because I prefer the look of the parallel sets p
  • Vertx FileUpload上传不带扩展名的文件

    我在用vertx web并尝试上传文件 这是我的代码 router route handler BodyHandler create setUploadsDirectory some path uploads router post api
  • pandas 计算两个零之间不为零的值的数量

    我有以下数据框 0 0 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 0 你如何获得一个看起来像这样的数据框 0 0 0 4 0 0 4 3 0 4 3 2 4 3 2 0 0 0 0 2
  • 将tiny int 转换为int 时出错

    该错误看起来是由于在服务器上安装框架 4 5 引起的 尽管该项目的目标仍然是 4 0 4 5 取代了 CLR 看起来它在将tinyint 类型的对象拆箱为 int 方面发生了变化 这在 4 0 中可以工作 但安装 4 5 后就不行了 请在回
  • PHP72 MongoDB 驱动程序与 OSX 上的 Homebrew

    我有一个问题可能表明我对 Homebrew 与 MongoDB 存在误解 我正在 Mac OSX 10 12 6 Sierra 上运行带有 PHP 7 2 1 我想使用 的 XAMPP 版本 我安装了 MongoDB 并创建了配置和数据存储
  • Apache HttpClient 4.3 SocketConfig.getSoTimeout() 与 RequestConfig.getSocketTimeout()

    当建造一个CloseableHttpClient在 Apache HttpClient 4 3 中 我可以使用 SocketConfig custom setSoTimeout soTimeout build 并将其发送至setDefaul
  • 计算变换球体的 AABB

    我有一个在对象空间中由中心点和半径表示的球体 使用可能包括缩放 旋转和平移的变换矩阵将球体变换为世界空间 我需要为世界空间中的球体构建一个轴对齐的边界框 但我不知道该怎么做 这是我目前的方法 适用于某些情况 public void comp
  • Ruby Savon Gem 更改日志记录配置

    我尝试在针对 WSDL 运行 Savon 时更改其日志记录 但更改日志记录级别未成功 我阅读了文档 http rubiii github com savon global configuration http rubiii github c
  • 如果使用相同的数组作为两个参数,strcat() 会崩溃

    char r 40 strcpy r abcdef strcat r r 我的程序在第三行崩溃了 替换 strcat r r 通过 strcat r abcdef 不过工作正常 这是为什么 根据strcat 3 http linux die
  • Django 管理模板覆盖不起作用

    姜戈 1 6 11 应用程序结构如下所示 my project new app templates 在我的配置中 TEMPLATE ROOT os path join BASE ROOT templates TEMPLATE DIRS TE
  • 匹配枚举引用的语法是什么?

    似乎 Rust 的每一份介绍性文档枚举类型 https doc rust lang org book first edition enums html解释如何match https doc rust lang org book first
  • 如何将S3中的10,000个文件公开

    我的存储桶中有一个文件夹 其中包含 10 000 个文件 似乎没有办法立即上传并公开它们 所以我把它们全部上传了 它们是私人的 我需要将它们全部公开 我尝试过 aws 控制台 它只是给出一个错误 对于文件较少的文件夹工作正常 我尝试过在 F
  • 如何从您的脚本执行另一个 python 脚本并能够进行调试?

    您有包装器 python 脚本正在调用另一个 python 脚本 当前正在使用os system python another py some params 您希望能够调试这两个脚本 并且如果您使用os system 您将丢失调试器 因此使
  • C 扩展中 IO 有界线程的 GIL (HDF5)

    我有一个采样应用程序 它获取250 000每秒采样 将它们缓冲在内存中并最终附加到HDFStore由 提供pandas 总的来说 这很棒 但是 我有一个线程运行并不断清空数据采集设备 DAQ 并且它需要定期运行 大约一秒的偏差往往会破坏东西