[英]R parallel write SEXP structure
我正在研究使用C / C ++代码的R中的数据处理模块,主要是出于速度方面的考虑。 这是我的问题的事实清单。
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的地方。 程序的逻辑确保了永远不会发生由不同线程写入同一位置的情况,即Consumer
类中的idx
和i
组合最多只能发生一次。 我遇到了各种奇怪的问题,例如“堆栈不平衡”或“陷入错误的生成”等。我缺少什么吗? 还是不建议在多个线程中调用SET_STRING_ELT? 非常感谢你!
除非您知道自己在做什么,否则不应在线程中调用C / R API函数,例如mkCharLen
可能会修改用于所有R字符串的内部哈希表,因此您不能在线程中调用此函数。 SET_STRING_ELT
在线程中也可能不可用,尤其是在写屏障打开的情况下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.