Qt QFuture Memoryleak
我想并行化一个函数,但有一个问题,几个小时后我的内存过载 这个测试程序计算出一些简单的东西,目前为止还有效。只有内存使用量在不断增加 QT项目文件:Qt QFuture Memoryleak,qt,memory-leaks,parallel-processing,qfuture,Qt,Memory Leaks,Parallel Processing,Qfuture,我想并行化一个函数,但有一个问题,几个小时后我的内存过载 这个测试程序计算出一些简单的东西,目前为止还有效。只有内存使用量在不断增加 QT项目文件: QT -= gui QT += concurrent widgets CONFIG += c++11 console CONFIG -= app_bundle DEFINES += QT_DEPRECATED_WARNINGS SOURCES += main.cpp QT程序文件: #include <QCoreApplication>
QT -= gui
QT += concurrent widgets
CONFIG += c++11 console
CONFIG -= app_bundle
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
QT程序文件:
#include <QCoreApplication>
#include <qdebug.h>
#include <qtconcurrentrun.h>
double parallel_function(int instance){
return (double)(instance)*10.0;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int nr_of_threads = 8;
double result_sum,temp_var;
for(qint32 i = 0; i<100000000; i++){
QFuture<double> * future = new QFuture<double>[nr_of_threads];
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread] = QtConcurrent::run(parallel_function,thread);
}
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread].waitForFinished();
temp_var = future[thread].result();
qDebug()<<"result: " << temp_var;
result_sum += temp_var;
}
}
qDebug()<<"total: "<<result_sum;
return a.exec();
}
#包括
#包括
#包括
双并行_函数(int实例){
返回(双倍)(实例)*10.0;
}
int main(int argc,char*argv[])
{
qcorea应用程序(argc、argv);
内螺纹数=8;
双结果总和,临时变量;
对于(qint32 i=0;i您存在内存泄漏,因为未删除future
数组。在外部for循环的末尾添加delete[]future
for(qint32 i = 0; i<100000000; i++)
{
QFuture<double> * future = new QFuture<double>[nr_of_threads];
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread] = QtConcurrent::run(parallel_function,thread);
}
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread].waitForFinished();
temp_var = future[thread].result();
qDebug()<<"result: " << temp_var;
result_sum += temp_var;
}
delete[] future; // <--
}
for(qint32 i=0;i内存泄漏,因为未删除future
数组。在外部for循环末尾添加delete[]future
for(qint32 i = 0; i<100000000; i++)
{
QFuture<double> * future = new QFuture<double>[nr_of_threads];
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread] = QtConcurrent::run(parallel_function,thread);
}
for(int thread = 0; thread < nr_of_threads; thread++){
future[thread].waitForFinished();
temp_var = future[thread].result();
qDebug()<<"result: " << temp_var;
result_sum += temp_var;
}
delete[] future; // <--
}
用于(qint32 i=0;i这可能看起来是这样的-注意每件事都可以简单得多!你死定要做手动内存管理:为什么?首先,QFuture
是一个值。你可以非常有效地将它存储在任何向量容器中,为你管理内存。你可以使用range for.Etc迭代这样的容器
QT = concurrent # dependencies are automatic, you don't use widgets
CONFIG += c++14 console
CONFIG -= app_bundle
SOURCES = main.cpp
尽管该示例是合成的,而且map\u函数非常简单,但还是值得考虑如何以最高效和最具表现力的方式进行操作。您的算法是典型的map reduce操作,blockingMappedReduce
的开销只有手动完成所有工作的一半
首先,让我们重写C++中的原始问题,而不是一些C语言的例子。
// https://github.com/KubaO/stackoverflown/tree/master/questions/future-ranges-49107082
/* QtConcurrent will include QtCore as well */
#include <QtConcurrent>
#include <algorithm>
#include <iterator>
using result_type = double;
static result_type map_function(int instance){
return instance * result_type(10);
}
static void sum_modifier(result_type &result, result_type value) {
result += value;
}
static result_type sum_function(result_type result, result_type value) {
return result + value;
}
result_type sum_approach1(int const N) {
QVector<QFuture<result_type>> futures(N);
int id = 0;
for (auto &future : futures)
future = QtConcurrent::run(map_function, id++);
return std::accumulate(futures.cbegin(), futures.cend(), result_type{}, sum_function);
}
我们还可以尝试使用随机访问迭代器:
using num_r_iterator = num_iterator<std::random_access_iterator_tag>;
result_type sum_approach5(int const N) {
return QtConcurrent::blockingMappedReduced(num_r_iterator{0}, num_r_iterator{N},
map_function, sum_modifier);
}
请注意,在随机iterable序列上使用map reduce比使用QtConcurrent::run
的开销低3个数量级以上,比非随机iterable解决方案快2个数量级。这可能看起来是这样的-请注意,一切都可以简单得多!您已经下定决心要做手动备忘了ry管理:为什么?首先,QFuture
是一个值。您可以将它非常高效地存储在任何向量容器中,该容器将为您管理内存。您可以使用range for.Etc迭代这样的容器
QT = concurrent # dependencies are automatic, you don't use widgets
CONFIG += c++14 console
CONFIG -= app_bundle
SOURCES = main.cpp
尽管该示例是合成的,而且map\u函数非常简单,但还是值得考虑如何以最高效和最具表现力的方式进行操作。您的算法是典型的map reduce操作,blockingMappedReduce
的开销只有手动完成所有工作的一半
首先,让我们重写C++中的原始问题,而不是一些C语言的例子。
// https://github.com/KubaO/stackoverflown/tree/master/questions/future-ranges-49107082
/* QtConcurrent will include QtCore as well */
#include <QtConcurrent>
#include <algorithm>
#include <iterator>
using result_type = double;
static result_type map_function(int instance){
return instance * result_type(10);
}
static void sum_modifier(result_type &result, result_type value) {
result += value;
}
static result_type sum_function(result_type result, result_type value) {
return result + value;
}
result_type sum_approach1(int const N) {
QVector<QFuture<result_type>> futures(N);
int id = 0;
for (auto &future : futures)
future = QtConcurrent::run(map_function, id++);
return std::accumulate(futures.cbegin(), futures.cend(), result_type{}, sum_function);
}
我们还可以尝试使用随机访问迭代器:
using num_r_iterator = num_iterator<std::random_access_iterator_tag>;
result_type sum_approach5(int const N) {
return QtConcurrent::blockingMappedReduced(num_r_iterator{0}, num_r_iterator{N},
map_function, sum_modifier);
}
如何使用Map Reduce对随机迭代序列的开销比使用<代码> QtReal:To运行3个数量级::运行,比非随机迭代解决方案快2个数量级。< /强> < / P>没有人应该编写使用生鲜新/删除的C++代码……这是非常糟糕的建议。避免内存泄漏的方法是不要试图使手动内存管理正确。避免内存泄漏的方法是编写代码,其中内存泄漏是不可能的。设计意味着编写C++,而不是C - C++ + -语法。任何人都不应该编写使用生鲜新/删除的C++代码……这是非常糟糕的建议。为了避免内存泄漏,不要试图更难获得手动内存管理。避免内存泄漏的方法是编写代码,其中内存泄漏是不可能的设计。这意味着编写C++,而不是C-USE-C++ + SythAcL。写得很好的答案。写得很好的答案。
sum: 4999995000000.000000 took 0.015778 ms/item
sum: 4999995000000.000000 took 0.003631 ms/item
sum: 4999995000000.000000 took 0.003610 ms/item
sum: 4999995000000.000000 took 0.005414 ms/item
sum: 4999995000000.000000 took 0.000011 ms/item
sum: 4999995000000.000000 took 0.000008 ms/item