【发布时间】:2019-04-23 03:51:59
【问题描述】:
我在 C#
上有这样的代码private static Random random = new Random();
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
Task.Factory.StartNew(() => {
System.Threading.Tasks.Parallel.For(0L, 10000000, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 }, n =>
{
Console.WirteLine(RandomString(12));
});
}
为其添加并行方法,它可以在不到 8 秒的时间内运行生成 1000 万个随机字符串并使用所有 CPU 功率
我尝试在 C++
中再次执行此操作string NonRepeatChar(int max_len)
{
std::string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(valid_chars.begin(), valid_chars.end(), g);
std::string rand_str(valid_chars.begin(), valid_chars.begin() + max_len);
return rand_str;
}
将代码应用到一些推荐的C++并行方法
void multiply()
{
for (size_t i = 0; i < 10; i++)
{
for (size_t j = 0; j < 10; j++)
{
for (int k = 0; k < 10; k++)
{
printf("%s\n",NonRepeatChar(10));
}
}
}
}
class Foo {
public:
Foo() : counter_(0) {}
std::pair<string, std::future<void>> a_function(std::future<void>& f) {
// Ensure that the background task from the previous iteration
// has completed
f.wait();
// Set the task for the next iteration
std::future<void> fut = std::async(std::launch::async, &Foo::background_task, this);
// Do some work
string value = NonRepeatChar(12);
// Return the result and the future for the next iteration
return std::make_pair(value.c_str(), std::move(fut));
}
void background_task() {
++counter_;
}
private:
std::atomic<int> counter_;
};
记录运行时间
int main()
{
clock_t tStart = clock();
std::future<void> bleak = std::async(std::launch::deferred, []() {});
Foo foo;
for (size_t i = 0; i < 10000; ++i) {
// Call the function
std::pair<string, std::future<void>> result = foo.a_function(bleak);
bleak = std::move(result.second);
std::cout << result.first << "\n";
}
printf("Time taken: %.2fs\n", (double)(clock() - tStart) / CLOCKS_PER_SEC);
return 0;
}
这是我的结果:
10.98s//正常循环
8.76s//乘法
8.88s//Foo
显然该代码与原始循环相比没有任何区别,仅生成 10000 行,甚至没有像 C# 那样使用所有 CPU 能力。并行方法有问题吗?我该如何优化它?
【问题讨论】:
-
您使用了哪些 C++ 编译器标志来编译您的程序?如果您正在运行未优化或“调试”构建,那么您向我们展示的有关时序信息的信息毫无意义。
-
Visual Studio,与 C# 相同。我使用的所有方法都不涉及外部库,如果这就是您的要求?
-
不,我要问的是您是否正在运行 C++ 代码的“调试”版本。如果是这样,那么将您的配置更改为“发布”并重建您的代码。一般来说,任何涉及 C++ 代码的速度或慢的问题都必须附带用于构建测试代码的编译器选项。
-
我只是将模式更改为“发布”,性能保持不变
-
好。关键是我们有太多的问题不得不关闭、删除或放弃,因为原始发布者没有运行发布版本,然后发现发布版本快得多,使得问题变得毫无意义。基准必须始终伴随着用于构建程序的选项。
标签: c++ performance parallel-processing parallel.foreach