gpt4 book ai didi

c++ - 从多个 C/C++ 线程调用 Haskell

转载 作者:行者123 更新时间:2023-12-01 13:07:39 24 4
gpt4 key购买 nike

我在编写的 Haskell 中有一个小函数,类型如下:

foreign export ccall sget :: Ptr CInt -> CSize -> Ptr CSize -> IO (Ptr CInt)

我从同时运行的多个 C++ 线程中调用它(通过
待定)。在执行程序的这一部分期间,我几乎无法获得
即使我在六核 CPU(12
逻辑核心)。因此,我怀疑要么调用 Haskell
通过单个线程汇集,或者有一些重要的
同步正在进行。

我没有明确地做任何这样的事情,所有的功能就是运行
在传入数据上(在将其存储到 Data.Vector.Storable 之后),以及
将结果作为新分配的数组返回(来自 Data.Marshal.Array)。

我需要做些什么来完全启用这样的并发调用吗?

我在 Debian Linux (bullseye/testing) 上使用 GHC 8.6.5,并且正在使用 -threaded -O2 进行编译。

期待阅读一些建议,

塞巴斯蒂安

最佳答案

使用此答案末尾的简单示例,如果我使用以下命令进行编译:

$ ghc -O2 Worker.hs
$ ghc -O2 -threaded Worker.o caller.c -lpthread -no-hs-main -o test

然后用 ./test 运行它100%只占用一个核心。我需要用 ./test +RTS -N 运行它,然后在我的 4 核桌面上,它以 400% 的速度运行,平均负载约为 4.0.0。

因此,RTS -N flag 影响可以同时运行导出的 Haskell 函数的并行线程的数量,并且不需要特殊操作(除了使用 -threaded 编译和使用 +RTS -n 运行)来充分利用所有可用内核。

因此,您的示例中一定有一些导致问题的原因。它可能是线程之间在某些共享数据结构上的争用。或者,并行垃圾收集可能会导致问题;我观察到随着 -N 的增加,并行 GC 会导致性能下降。在一个简单的测试用例中(遗憾的是忘记了细节),所以你可以尝试使用 -qg 关闭并行 GC或限制 -qn2 所涉及的核心数量或者其他的东西。要启用这些选项,您需要调用 hs_init_with_rtsopts()代替通常的 hs_init()就像我的例子一样。

如果这不起作用,我认为您将不得不尝试缩小问题范围并发布一个说明性能问题的最小示例以获得更多帮助。

我的例子:
caller.c
#include "HsFFI.h"
#include "Rts.h"
#include "Worker_stub.h"
#include <pthread.h>

#define NUM_THREAD 4

void*
work(void* arg)
{
for (;;) {
fibIO(30);
}
}

int
main(int argc, char **argv)
{
hs_init_with_rtsopts(&argc, &argv);

pthread_t threads[NUM_THREAD];
for (int i = 0; i < NUM_THREAD; ++i) {
int rc = pthread_create(&threads[i], NULL, work, NULL);
}
for (int i = 0; i < NUM_THREAD; ++i) {
pthread_join(threads[i], NULL);
}

hs_exit();
return 0;
}
Worker.hs
module Worker where

import Foreign

fibIO :: Int -> IO Int
fibIO = return . fib

fib :: Int -> Int
fib n | n > 1 = fib (n-1) + fib (n-2)
| otherwise = 1

foreign export ccall fibIO :: Int -> IO Int

关于c++ - 从多个 C/C++ 线程调用 Haskell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60711780/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com