printf除非换行符在格式字符串中,为什么在调用后不刷新?这是POSIX的行为吗?我怎么可能printf每次都立即冲洗?
我有一个Python程序,它产生许多线程,一次运行4个,每个执行一个昂贵的操作.伪代码:
for object in list:
t = Thread(target=process, args=(object))
# if fewer than 4 threads are currently running, t.start(). Otherwise, add t to queue
Run Code Online (Sandbox Code Playgroud)
但是当程序运行时,OS X中的Activity Monitor显示4个逻辑核心中的1个处于100%而其他核心处于接近0的状态.显然,我不能强制操作系统做任何事情,但我从来没有做过注意这样的多线程代码中的性能,所以我想知道我是否只是缺少或误解了一些东西.
谢谢.
我使用 Tensorflow,但我正在为用户编写文档,这些文档通常会因深度学习框架而异。
当处理不适合本地文件系统 (TB+) 的数据集时,我从远程数据存储中采样数据并将样本在本地写入 Tensorflow 标准tfrecords格式。
在训练的第一个 epoch 期间,我将只采样几个值,因此本地数据的epoch非常小,我对其进行训练。在epoch 2 上,我重新检查我的采样子流程(现在更多)生成了哪些数据文件,并在下一个 epoch 的本地数据文件的扩展集上进行训练。每个时期重复该过程。通过这种方式,我建立了一个本地样本缓存,并可以在我填满本地存储时驱逐旧样本。本地样本缓存大约在模型最需要方差的时间增长(朝向训练的后期)。
在 Python/Tensorflow 中,重要的是我不要在 Python 训练循环过程中反序列化数据,因为 Python GIL 无法支持数据传输速率(300-600 MB/秒,数据是原始科学不可压缩的),因此 GPU 性能当 Python GIL 无法快速为训练循环提供服务时,就会受到影响。
将样本tfrecords从子进程(python 多处理)写入文件允许 tensorflow 的本机TFRecordsDataset在 Python 之外进行反序列化,因此我们避开了 Python GIL 问题,并且我可以使 GPU 达到高 IO 数据速率。
我想知道我将如何在 Pytorch 中解决这个问题。我正在撰写有关正在使用的采样策略的文章,并希望向 Tensorflow 和 PyTorch 的用户提供具体的建议,但我对 PyTorch 预处理生态系统的了解不够深入,无法写出足够详细的内容。
旁注:支持这些数据传输率的唯一基于 Python 的解决方案可能来自 Python 3.8,它带有 System V 共享内存和多处理,但我还没有尝试过,因为对它的支持还不够(很快就会)。现有的多处理解决方案是不够的,因为它们需要在训练循环过程中进行反序列化,因此在反序列化期间以高 IO 速率锁定 GIL。
因此,我正在构建一个长期运行的查询Web应用程序以供内部使用。
我的目标是拥有一个带有守护进程的flask应用程序,该守护进程在服务器启动时启动,它将更新全局字典对象。
我不一定要发布任何示例代码,因为我尝试了许多方法,但都没有成功。
守护程序将创建一个线程池(multiprocessing.Pool)以遍历所有数据库实例,并对它们运行几个查询。
看来,无论我如何尝试实施(现在,使用flask开发服务器),它都将锁定应用程序,并且在运行时无法执行任何其他操作。我曾尝试阅读大量文档,但通常还是会假设很多其他知识,但最终我不知所措。
我想知道是否有人可以提供一些指导,即使是在我可以找到的地方,因为我到处搜索了“烧瓶启动例程”和类似的东西,但没有发现任何用处。看来,当我将其部署到服务器上时,也许可以在.wsgi文件中定义一些启动守护程序,但是在那之前还有什么方法可以在本地执行此操作?当我将其推出以用于一般用途时,这甚至是正确的方法吗?
否则,我只是在考虑建立一个cron作业,该作业连续运行一个python脚本来执行我需要的查询,然后转储到MongoDB实例或其他东西,以便客户端可以从中进行提取(就像执行所有查询一样)在Flask应用程序的服务器端只是锁定了服务器,因此无法执行其他操作-aka:无法对信息采取行动,杀死spids等)
任何帮助都将极大地帮助我,我的大脑已经旋转了好几天。
from flask import Flask
from celery import Celery
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'amqp://guest@localhost//'
app.config['CELERY_RESULT_BACKEND'] = 'amqp://guest@localhost//'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
output = 0
@app.before_first_request
def init():
task = my_task.apply_async()
@app.route('/')
def hello_world():
global output
return 'Hello World! - ' + str(output)
@celery.task
def my_task():
global output
result = 0
for i in range(100):
result += i
output = result
if __name__ == '__main__':
app.run()
Run Code Online (Sandbox Code Playgroud) 关于Python ayncio的代码示例: run_in_executor
import asyncio
import concurrent.futures
def blocking_io():
# File operations (such as logging) can block the
# event loop: run them in a thread pool.
with open('/dev/urandom', 'rb') as f:
return f.read(100)
def cpu_bound():
# CPU-bound operations will block the event loop:
# in general it is preferable to run them in a
# process pool.
return sum(i * i for i in range(10 ** 7))
async def main():
loop = asyncio.get_running_loop()
## Options:
# …Run Code Online (Sandbox Code Playgroud) 根据我所读到的内容(例如此处),我了解 I/O 操作释放了 GIL。因此,如果我必须读取本地文件系统上的大量文件,我的理解是线程执行应该加快速度。
\n为了测试这个 - 我有一个文件夹(input ),其中包含大约 100k 个文件 - 每个文件只有一行,其中包含一个随机整数。我有两个函数 - 一个“顺序”和一个“并发”,只需添加所有数字
import glob\nimport concurrent.futures\nALL_FILES = glob.glob(\'./input/*.txt\')\n \ndef extract_num_from_file(fname):\n #time.sleep(0.1)\n with open(fname, \'r\') as f:\n file_contents = int(f.read().strip())\n return file_contents\n\ndef seq_sum_map_based():\n return sum(map(extract_num_from_file, ALL_FILES)) \n\ndef conc_sum_map_based():\n with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n return sum(executor.map(extract_num_from_file, ALL_FILES))\nRun Code Online (Sandbox Code Playgroud)\n虽然这两个函数给出了相同的结果 - “并发”版本大约慢 3-4 倍。
\nIn [2]: %timeit ss.seq_sum_map_based() \n3.77 s \xc3\x82\xc2\xb1 50.2 ms per loop (mean \xc3\x82\xc2\xb1 std. dev. of 7 runs, 1 loop each)\n\nIn [3]: %timeit …Run Code Online (Sandbox Code Playgroud) python ×5
async-await ×1
c ×1
concurrency ×1
flask ×1
flush ×1
gil ×1
performance ×1
printf ×1
python-3.x ×1
pytorch ×1