我正在为Unity项目构建一个不受管理的C ++ Dll插件,其中该插件与2个传感器API交互,运行重复的传感器融合算法,并通过回调函数返回最终结果。该项目在Windows 10 64bit上运行。在我尝试将Unity项目构建为独立版本之前,所有功能都在Unity编辑器中顺利运行。在 build 模式下,传感器融合算法循环具有恒定的“打ic”,其中执行时间将在一到两次迭代中不断增加10倍。
我不希望答案能够直接解决我的问题,因为该问题可能是针对具体情况的,但是我希望有经验的人可以就可能出什么问题分享一些见解。我已经尝试了下一节中提到的内容。
extern "C" {
void start(FilterWrapper *& pWrapper, Callback cb) {
pWrapper = new FilterWrapper();
// code registers callback
}
void stop(FilterWrapper *& pWrapper) {
pWrapper->stopFilter();
delete pWrapper;
pWrapper = NULL;
}
}
Class FilterWrapper
{
public:
FilterWrapper();
~FilterWrapper();
void stopFilter();
private:
void sampleSensor1();
void sampleSensor2();
void processData();
void runAlgorithm();
bool stop_condition = false;
std::thread thread1,thread2,thread3,thread4;
std::deque<float> bufferA,bufferB,bufferC;
std::mutex mtxA,mtxB,mtxC;
};
FilterWrapper::FilterWrapper() {
thread1 = std::thread(&FilterWrapper::sampleSensor1,this);
thread2 = std::thread(&FilterWrapper::sampleSensor2,this);
thread3 = std::thread(&FilterWrapper::processData,this);
thread4 = std::thread(&FilterWrapper::runAlgorithm,this);
}
void FilterWrapper::stopFilter() {
stop_condition = true;
if (thread1.joinable()) thread1.join();
// same for other threads ...
}
void FilterWrapper::sampleSensor1() {
while(!stop_condition) {
// code sample data
std::lock_guard<std::mutex> lck(mtxA);
bufferA.push_back(data);
}
}
void FilterWrapper::sampleSensor2() {
while(!stop_condition) {
// code sample data
std::lock_guard<std::mutex> lck(mtxB);
bufferB.push_back(data);
}
}
void FilterWrapper::processData() {
while(!stop_condition) {
float data;
{
std::lock_guard<std::mutex> lck(mtxA);
if (bufferA.empty()) continue;
data = bufferA.front();
bufferA.pop_front();
}
// code process data...
std::lock_guard<std::mutex> lck(mtxC);
bufferC.push_back(data);
}
}
void FilterWrapper::runAlgorithm() {
while(!stop_condition) {
float data1, data2;
{
std::lock_guard<std::mutex> lck(mtxB);
if (bufferB.empty()) continue;
data1 = bufferB.front();
bufferB.pop_front();
}
{
std::lock_guard<std::mutex> lck(mtxC);
if (bufferC.empty()) continue;
data1 = bufferC.front();
bufferC.pop_front();
}
std::chrono::stead_clock::time_point t_start = std::chrono::stead_clock::now();
// run the algorithm with data1 and data2 ...
std::chrono::stead_clock::time_point t_end = std::chrono::stead_clock::now();
std::chrono::duration<float,std::milli> dur = t_end-t_start;
std::cout << "algorithm time: " << dur.count() << "\n";
}
}
在DLL内
在Unity方面
我首先在C ++控制台应用程序项目中开发和验证了算法和多线程,然后将这些类和函数复制到DLL项目,并编写了 FilterWrapper 类。在C ++控制台应用程序以及Unity编辑器模式下,算法循环中每次迭代的执行时间始终约为9 ms,而传感器数据处理循环中每次迭代的执行时间始终为12 ms。但是,在构建Unity项目时,执行时间可能经常分别飙升至30 ms和90 ms。
当作为DLL导入时,C ++代码在控制台应用程序或Unity编辑器模式下均可正常运行,但在将Unity项目构建到独立应用程序中时,则非常不稳定且运行缓慢。正如人们经常说的那样,“编辑器”模式会产生大量开销,因此人们希望在构建项目时性能通常会更好。看来我的情况恰恰相反。我已经排除了图形问题,因为Unity场景中实际上没有任何东西,并且我认为在构建项目时会有一些环境因素发生变化,但是我不确定要看哪里。