我只是自学了一些 OpenMP,这可能很愚蠢。基本上,我试图在 C++ 中并行化广度优先搜索程序,每个节点都需要很长时间来处理。这是一个示例代码:
queue<node*> q;
q.push(head);
while (!q.empty()) {
qSize = q.size();
for (int i = 0; i < qSize; i++) {
node* currNode = q.front();
q.pop();
doStuff(currNode);
q.push(currNode);
}
}
Run Code Online (Sandbox Code Playgroud)
处理函数 doStuff() 非常昂贵,我想对其进行并行化。但是,如果我通过将 for 循环放在#pragma omp parallel forfor 行之前来并行化 for 循环,则在运行时会弹出各种奇怪的错误。我猜测原因是这种方式q.front()并且q.push()也会并行化,并且多个线程可能会通过同一个节点q.front()(因为它们都在处理之前q.push就被处理了)。
我怎样才能解决这个问题?
我有一个可以随时启动或停止的程序。该程序用于从网页下载数据。首先,用户将在一个.csv文件中定义一堆网页,然后保存该.csv文件,然后启动程序。该程序将读取该.csv文件并将其转换为作业列表。接下来,作业被分成 5 个独立的downloader功能,这些功能并行工作但可能需要不同的时间来下载。
在downloader(其中有 5 个)完成下载网页后,我需要它来打开.csv文件并删除链接。这样,随着时间的推移,.csv文件会越来越小。问题是有时两个download函数会尝试同时更新.csv文件,会导致程序崩溃。我该如何处理?
我正在研究最初为多核处理器系统开发的遗留应用程序。为了利用多核处理,已经使用了 OpenMP 和 PPL。现在,一项新要求是在具有多个 NUMA 节点的系统上运行该软件。目标操作系统是 Windows 7 x64。
我已经执行了几次测量,并注意到在将应用程序分配给单个 NUMA 节点时执行时间是最佳的,因此浪费了一个完整的处理器。应用程序的许多部分执行数据并行算法,例如,并行处理向量的每个元素,并将结果写入另一个向量,如下例所示
std::vector<int> data;
std::vector<int> res;
// init data and res
#pragma omp parallel for
for (int i = 0; i < (int) data.size(); ++i)
{
res[i] = doExtremeComplexStuff(data[i]);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,此类算法的性能下降是由来自第二个 NUMA 节点的非本地内存访问引起的。所以问题是如何让应用程序表现得更好。
对非本地内存的只读访问是否以某种方式透明加速(例如,通过操作系统将数据从一个节点的本地内存复制到另一个节点的本地内存)?我是否必须拆分问题大小并将输入数据复制到相应的 NUMA 节点,对其进行处理,然后再次组合所有 NUMA 节点的数据以提高性能?
如果是这种情况,是否有 std 容器的替代方案,因为它们在分配内存时不是 NUMA 感知的?
我试过使用
#!/bin/bash
python ScriptA.py &
python ScriptB.py &
Run Code Online (Sandbox Code Playgroud)
同时运行这两个脚本,但它总是使用 ScriptA 返回“无效语法”,即使所有 python 文件都在同一个文件夹中。
运行这两个脚本的文件:
def song():
user = input()
if user == "Chance":
python ScriptA.py &
python ScriptB.py &
else:
print("Error")
Run Code Online (Sandbox Code Playgroud)
到目前为止,我找到的解决方案(例如将该脚本放在一行中)不起作用,因为错误仍然显示。
- - - - - - - - - - - - - 编辑 - - - - - - - - - - - - ---
然而,这两个脚本单独运行良好,您提供的所有解决方案仍按顺序运行。脚本 A 是通过 OpenCV 播放的视频,脚本 B 是通过播放声音播放的歌曲。
脚本A:
import cv2
import numpy as np
import os
os.environ['SDL_VIDEO_CENTERED'] = '1'
cap = …Run Code Online (Sandbox Code Playgroud) 我正在 CentOS HPC 上使用 tensorflow 训练我的神经网络。但是我在训练过程开始时遇到了这个错误:
OMP:错误 #15:正在初始化 libiomp5.so,但发现 libiomp5.so 已经初始化。OMP:提示:这意味着 OpenMP 运行时的多个副本已链接到程序中。这是危险的,因为它会降低性能或导致错误的结果。最好的办法是确保只有一个 OpenMP 运行时链接到进程中,例如避免在任何库中静态链接 OpenMP 运行时。作为不安全、不受支持、未记录的解决方法,您可以设置环境变量 KMP_DUPLICATE_LIB_OK=TRUE 以允许程序继续执行,但这可能会导致崩溃或静默产生错误结果。有关更多信息,请参阅http://www.intel.com/software/products/support/。
例如,代码是分段的,它对很多人都很好,但在我的情况下却失败了。
为什么会发生?如何解决?
我正在尝试对生化过程进行建模,并将我的问题构建为一个优化问题,我使用differential_evolutionscipy解决 了这个问题。
到目前为止,一切都很好,我对具有 15-19 个参数的简化模型的实现感到非常满意。
我扩展了模型,现在有 32 个参数,时间太长了。并非完全出乎意料,但仍然是一个问题,因此是一个问题。
我已经看到:
- 一个几乎相同的 R 并行差分进化问题
- 以及一个关于该主题 的 github 问题https://github.com/scipy/scipy/issues/4864
但它想留在 python 中(模型在 python 管道内),并且拉取请求尚未导致并正式接受解决方案,尽管已经提出了一些选项。
此外,我无法并行化要优化的函数中的代码,因为这是一系列顺序计算,每个计算都需要上一步的结果。理想的选择是有一些东西可以并行评估一些个体并将它们返回到总体中。
总结:
- scipy 中是否有任何选项允许我愚蠢地忽略的差异进化的并行化?(理想的解决方案)
- 是否有关于 scipy 中的替代算法的建议,该算法要么(方式)串行更快或可能并行化?
- 有没有其他好的软件包可以提供并行化的差分进化功能?或者其他适用的优化方法?
- 健全性检查:我是否用 32 个参数重载了 DE,我需要从根本上改变方法?
PS
我是一名生物学家,正式的数学/统计并不是我的强项,任何公式到英语的翻译都会非常感激:)
PPS
作为一个极端的选择,我可以尝试迁移到 R,但我无法编写 C/C++ 或其他语言。
python parallel-processing mathematical-optimization scipy differential-evolution
我有以下(大)文件,其中包含 30233088 个字符串:
head mystringfile.txt:
GAATGAACACGAAGAA
GAATGAACACGAAGAC
GAATGAACACGAAGAG
GAATGAACACGAAGCA
Run Code Online (Sandbox Code Playgroud)
cat sequence.txt
AAATAGAGGGCGGTCCAGGCGTGTCGAAACACTGGGTCCAGGGCAAGAGCGGTTCGGGTGTCAGGAAAGCCCCCAAGGGGGTTCGCGCGGTTTGCAGTGAGGTAGAGGCCGGTGTATGGGTAGACAATTGGGGTCCCAAAGAAAAAGGCTCGTCCAACATCATAATAAACCCAAGCACGATAAAAAGCAAACGCAGACTTCAATAGGGTACGAGCAATTGTGGCAGGGTGCTCGCTGTCAGGGTTAGATCTTCTTGGAGTCGCGTCGCTCGGGGGGGCAAGGCCAACGTAAGATCGTGGCTGATCGCTGGCAATGCGGTCGGTTGGGTGGTCGCTAGTAGGGGCACGGCGGTCTCTTATGGCGTCGTAAAATGCGTCTCCAAAGCGAAAAGGGGCGGCAGACAAGTCACCGGGCAAGCTTAGAGGTCTGGGGCCCGTGGCTTTAGGGGAATGAACACGAAGACGCGAAACGAAGTCGTGTTTCTTGTTGGCTGTAGAGGGGAAAACCGTCTGGGGCGATCTGGCGTAGTAGTGCGTGTCTTGCAGTGAGCTCCCCGTCCGTAAGGATTCGCAGGAATCCTGCGTGAAGCTCGGTCGTCTCGGCCGTGTCTCGGGGTTTGATTGCGGGTTCAGATTGGAAAGGTCTCCTCGGGTCGTTTGCTGCATTTGCTCGCAACCCTGACGTGAAAGGGGTGAGCTGTCTCCAATCTGCCACGCTGGGTGTTGCGTCGTCAGTAAAAGACTTGGTCAAGCTGGGACCTCGCAAGATCGCGAGAGGGTTAAGCACAAAAGGTATGGCGAAGCTCCCGGGTGCTCTTGTGGCCACCCAGAATCATGGTGACGTAGGTTTTGCGAAGCCATCAAAAATTCAGGCGGCAAAACGAGCCAGTAGGGTCCTGGGCAGCTGGGCTTGTAGTGGGTAGGCGGCAAAACGCAAAGAATGAACACGAAGCAACTCCGTAGTGTGACGGGGGTTCTGACAAACGTCCTGCAAGAAGTTCGTCTTGGG
Run Code Online (Sandbox Code Playgroud)
我需要grep在另一个序列文件中确定匹配的位置,我执行以下操作:
while read line; do grep -b -o $line sequence.txt >>sequence.txt.count; done<mystringfile.txt
Run Code Online (Sandbox Code Playgroud)
像这样运行代码当然需要很长时间并且只运行 1 个线程的一部分,那么我如何修改它(使用parallel或xargs?),以便它在我想要指定的尽可能多的线程上运行?
我有一个目录树
working_dir\
main.py
my_agent\
my_worker.py
my_utility\
my_utils.py
Run Code Online (Sandbox Code Playgroud)
每个文件中的代码如下
""" main.py """
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from my_agent.my_worker import MyWorker
import ray
ray.init()
workers = [MyWorker.remote(i) for i in range(10)]
ids = [worker.get_id.remote() for worker in workers]
# print(*ids, sep='\n')
print(*ray.get(ids), sep='\n')
Run Code Online (Sandbox Code Playgroud)
""" worker.py """
from my_utility import my_utils
import ray
@ray.remote
class MyWorker():
def __init__(self, id):
self.id = id
def get_id(self):
return my_utils.f(self.id)
Run Code Online (Sandbox Code Playgroud)
""" my_utils.py """
def f(id):
return '{}: Everything is fine...'.format(id)
Run Code Online (Sandbox Code Playgroud)
这是我收到的错误消息的一部分
回溯(最近一次调用最后一次):
文件“/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/function_manager.py”,第 616 行,在 fetch_and_register_actor unpickled_class …
使用 的最佳实践是什么.stream().parallel()?
例如,如果您有一堆阻塞 I/O 调用并且您想检查 if .anyMatch(...),那么并行执行此操作似乎是明智之举。
示例代码:
public boolean hasAnyRecentReference(JobId jobid) {
<...>
return pendingJobReferences.stream()
.parallel()
.anyMatch(pendingRef -> {
JobReference readReference = pendingRef.sync();
Duration referenceAge = timeService.timeSince(readReference.creationTime());
return referenceAge.lessThan(maxReferenceAge)
});
}
Run Code Online (Sandbox Code Playgroud)
乍一看这看起来很合理,因为我们可以同时执行多个阻塞读取,因为我们只关心匹配的任何一个,而不是一个接一个地检查(所以如果每次读取需要 50 毫秒,我们只需要等待 ( 50ms * expectedNumberOfNonRecentRefs ) / numThreads)。
在生产环境中引入此代码是否会对代码库的其他部分产生任何不可预见的性能影响?
java parallel-processing concurrency forkjoinpool java-stream
这是我想要并行运行 printRange() 的简单代码:
def printRange(lrange):
print ("First is " + str(lrange[0]) + " and last is " + str(lrange[1]))
def runInParallel():
ranges = [[0, 10], [10, 20], [20, 30]]
// Call printRange in parallel with each sublist of ranges given as argument
Run Code Online (Sandbox Code Playgroud)
我的问题与这里的 SO 问题不同,每个过程都是硬编码的,开始并最终加入。我想与其他 100 个 printRange() 工作函数并行运行 printRange()。每次硬编码是不可行的。这怎么可能?
python ×6
openmp ×3
c++ ×2
awk ×1
concurrency ×1
forkjoinpool ×1
grep ×1
java ×1
java-stream ×1
numa ×1
ray ×1
scipy ×1
scripting ×1
tensorflow ×1
xargs ×1