gpt4 book ai didi

c++ - R并行写入SEXP结构

转载 作者:搜寻专家 更新时间:2023-10-31 01:41:13 25 4
gpt4 key购买 nike

我正在使用 C/C++ 代码在 R 中开发一个数据处理模块,主要是出于速度原因。这是我的问题的事实列表。

  • 最终结果数据是一个字符串 vector 列表,占用 20MB 到 200MB 的内存。
  • 数据处理可以适应单生产者/多消费者模型。
  • wrap 花费了大量时间转换 vector<vector<string> >List用于我的数据。

因此我打算直接在 SEXP 结构中工作,这样我可能会节省最终转换的时间。我的主要功能如下所示。

boost::atomic<bool> done(false);
SEXP myfun(...) {
...
SEXP sdataStr;
PROTECT(sdataStr=allocVector(VECSXP, nElem));
vector<SEXP> dataStr(nElem);
for (int i=0; i<nElem; ++i) {
dataStr[i]=SET_VECTOR_ELT(sdataStr, i, allocVector(STRSXP, n));
}
Producer producer(&queue);
Consumer consumer1(dataStr, nElem, &queue);
Consumer consumer2(dataStr, nElem, &queue);

boost::thread produce(producer);
boost::thread consume1(consumer1);
boost::thread consume2(consumer2);

produce.join();
done=true;
consume1.join();
consume2.join();
UNPROTECT(1);
return sdataStr;
}

我的消费者类是这样的

class Consumer {
vector<SEXP>& m_dataStr;
boost::lockfree::queue<buffer>* m_queue;
buffer m_buffer;

public:
Consumer(vector<SEXP>& dataStr, boost::lockfree::queue<buffer>* queue) : m_dataStr(dataStr), m_queue(queue) {}

void operator()() {
while (!done) {
while (m_queue->pop(m_buffer)) {
process_item();
}
}
while (m_queue->pop(m_buffer)) {
process_item();
}
}

private:
process_item() {
...
// for some 0<=idx<nElem, 0<=i<n, some char* f and integer len
SET_STRING_ELT(m_dataStr[idx], i, mkCharLen(f,len));
...
}
}

这些是我唯一使用 Rinternals 的地方。该程序的逻辑确保不会发生不同线程写入同一位置的情况,即 idx。和 i组合 Consumer类最多可以出现一次。我遇到了各种奇怪的问题,比如“stack imbalance”,或者“snaping into wrong generation”等等。有什么我想念的吗?或者不建议在多线程中调用 SET_STRING_ELT?非常感谢!

最佳答案

除非您知道自己在做什么,否则不应在线程中调用 C/R API 函数,例如 mkCharLen 可能会修改用于所有 R 字符串的内部哈希表,因此您可以不要在线程中调用它。 SET_STRING_ELT 也可能在线程中不可用,尤其是在写屏障打开的情况下。

关于c++ - R并行写入SEXP结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28774804/

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