【发布时间】:2014-05-28 13:30:33
【问题描述】:
这是一个后续问题,该问题解决了带有线程局部变量 Parallel::For with local variable 的 Parallel::For 语法
我尝试实现的书籍示例在整数上执行 Interlocked::Add,但我的实现需要双精度数。在上面引用的代码中,我实现了一个 Lock 例程,但这不起作用。所以我现在正在尝试将 C# 示例转换为 C++\Cli 类,然后我可以将其作为双精度的安全添加来调用 Interlocked.CompareExchange
TreadSafe.h
using namespace System;
using namespace System::Threading;
ref class ThreadSafe
{
private:
double totalValue;
public:
property double Total
{
double get()
{
return totalValue;
}
}
double AddToTotal(double addend);
// constructor
ThreadSafe(void);
};
ThreadSafe.cpp
// constructor
ThreadSafe::ThreadSafe(void)
{
totalValue = 0.0;
}
double ThreadSafe::AddToTotal(double addend)
{
double initialValue, computedValue;
do
{
initialValue = totalValue;
computedValue = initialValue + addend;
}
while (initialValue != Interlocked::CompareExchange(totalValue, computedValue, initialValue));
return computedValue;
}
然后我在包含 Parallel:For 例程的类中调用它,该例程也在上面引用的帖子中列出。
DataCollection.cpp
// constructor
DataCollection::DataCollection(Form1^ f1) // takes parameter of type Form1 to give acces to variables on Form1
{
this->f1 = f1;
ts = gcnew ThreadSafe();
}
// initialize data set for parallel processing
void DataCollection::initNumbers(int cIdx, int gIdx)
{
DataStructure^ number;
numbers = gcnew List<DataStructure^>();
for (int i = 0; i < f1->myGenome->nGenes; i++)
{
// creates collection "numbers" with data to be processed in parallel
}
}
// parallel-for summation of scores
double DataCollection::sumScore()
{
Parallel::For<double>(0, numbers->Count, gcnew Func<double>(this, &DataCollection::initSumScore),
gcnew Func<int, ParallelLoopState^, double, double>(this, &DataCollection::computeSumScore),
gcnew Action<double>(this, &DataCollection::finalizeSumScore));
return ts->Total;
}
// returns start value
double DataCollection::initSumScore()
{
return 0.0;
}
// perform sequence alignment calculation
double DataCollection::computeSumScore(int k, ParallelLoopState^ status, double tempVal)
{
// calls several external methods, but for testing simplified to an assignment only
tempVal += 1.0;
return tempVal;
}
// locked addition
void DataCollection::finalizeSumScore(double tempVal)
{
ts->AddToTotal(tempVal);
}
代码编译并运行,但没有添加。它总是返回 0。
所以我假设我对 C# 示例的翻译/实现不正确。怎么了?
【问题讨论】:
-
你读过 Raymond Chen 的博客上的An extensible interlocked arithmetic function 了吗?无需使用 lambda,但请务必了解发生了什么。
-
感谢您的链接。然而,他也将 C++ 实现留给了读者。起点与我提到的第二个参考非常相似。无论如何,上述工作。
标签: .net multithreading parallel-processing c++-cli