c++ - 多线程性能 std::string

标签 c++

我们正在一个使用 OpenMP 的项目上运行一些代码,我遇到了一些奇怪的事情。我已经包含了一些演示我所看到的内容的播放代码的一部分。

测试比较了在多线程循环中调用带有 const char* 参数的函数和 std::string 参数。这些函数基本上什么都不做,因此没有开销。

我所看到的是完成循环所需时间的主要差异。对于执行 100,000,000 次迭代的 const char* 版本,代码需要 0.075 秒才能完成,而 std::string 版本需要 5.08 秒。这些测试是在 Ubuntu-10.04-x64 上用 gcc-4.4 完成的。

我的问题基本上是这是否完全是由于 std::string 的动态分配以及为什么在这种情况下无法优化,因为它是 const 且无法更改?

代码如下,非常感谢您的回复。

编译:g++ -Wall -Wextra -O3 -fopenmp string_args.cpp -o string_args

#include <iostream>
#include <map>
#include <string>
#include <stdint.h>

// For wall time
#ifdef _WIN32
#include <time.h>
#else
#include <sys/time.h>
#endif

namespace
{
  const int64_t g_max_iter = 100000000;
  std::map<const char*, int> g_charIndex = std::map<const char*,int>();
  std::map<std::string, int> g_strIndex = std::map<std::string,int>();

  class Timer
  {
  public:
    Timer()
    {
    #ifdef _WIN32
      m_start = clock();
    #else /* linux & mac */
      gettimeofday(&m_start,0);
    #endif
    }

    float elapsed()
    {
    #ifdef _WIN32
      clock_t now = clock();
      const float retval = float(now - m_start)/CLOCKS_PER_SEC;
      m_start = now;
    #else /* linux & mac */
      timeval now;
      gettimeofday(&now,0);
      const float retval = float(now.tv_sec - m_start.tv_sec) + float((now.tv_usec - m_start.tv_usec)/1E6);
      m_start = now;
    #endif
      return retval;
    }

  private:
    // The type of this variable is different depending on the platform
#ifdef _WIN32
    clock_t
#else
    timeval
#endif
    m_start;   ///< The starting time (implementation dependent format)
  };

}

bool contains_char(const char * id)
{
  if( g_charIndex.empty() ) return false;
  return (g_charIndex.find(id) != g_charIndex.end());
}

bool contains_str(const std::string & name)
{
  if( g_strIndex.empty() ) return false;
  return (g_strIndex.find(name) != g_strIndex.end());
}

void do_serial_char()
{
  int found(0);
  Timer clock;
  for( int64_t i = 0; i < g_max_iter; ++i )
  {
    if( contains_char("pos") )
    {
     ++found;
    }
  }
  std::cout << "Loop time: " << clock.elapsed() << "\n";
  ++found;
}

void do_parallel_char()
{
  int found(0);
  Timer clock;
#pragma omp parallel for
  for( int64_t i = 0; i < g_max_iter; ++i )
  {
    if( contains_char("pos") )
    {
     ++found;
    }
  }
  std::cout << "Loop time: " << clock.elapsed() << "\n";
  ++found;
}

void do_serial_str()
{
  int found(0);
  Timer clock;
  for( int64_t i = 0; i < g_max_iter; ++i )
  {
    if( contains_str("pos") )
    {
     ++found;
    }
  }
  std::cout << "Loop time: " << clock.elapsed() << "\n";
  ++found;
}

void do_parallel_str()
{
  int found(0);
  Timer clock;
#pragma omp parallel for
  for( int64_t i = 0; i < g_max_iter ; ++i )
  {
    if( contains_str("pos") )
    {
     ++found;
    }
  }
  std::cout << "Loop time: " << clock.elapsed() << "\n";
  ++found;
}

int main()
{
  std::cout << "Starting single-threaded loop using std::string\n";
  do_serial_str();
  std::cout << "\nStarting multi-threaded loop using std::string\n";
  do_parallel_str();

  std::cout << "\nStarting single-threaded loop using char *\n";
  do_serial_char();
  std::cout << "\nStarting multi-threaded loop using const char*\n";
  do_parallel_char();
  }

最佳答案

My question is basically whether this is solely due the dynamic allocation of std::string and why in this case that can't be optimized away since it is const and can't change?

是的,这是由于每次迭代都会对 std::string 进行分配和复制。

A sufficiently smart compiler可能会对此进行优化,但当前的优化器不太可能发生这种情况。相反,您可以自己提升绳子:

void do_parallel_str()
{
  int found(0);
  Timer clock;
  std::string const str = "pos";  // you can even make it static, if desired
#pragma omp parallel for
  for( int64_t i = 0; i < g_max_iter; ++i )
  {
    if( contains_str(str) )
    {
      ++found;
    }
  }
  //clock.stop();  // Or use something to that affect, so you don't include
  // any of the below expression (such as outputing "Loop time: ") in the timing.
  std::cout << "Loop time: " << clock.elapsed() << "\n";
  ++found;
}

关于c++ - 多线程性能 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4818039/

相关文章:

c++ - 声明 QStringList 时出错

c# - 在 C# 中调用 C++ 导出的函数

c++ - Visual Studio 我认为堆错误

c++ - 即使在设计器中更改高度后,组合框下拉菜单也不起作用

c++ - 转换运算符到 std::complex<double>

python - 从 c++ 中的 python 程序中检索 stderr

c++ - 如何让 cin 停止跳过?

c++ - 如何使用 ArduinoJson 从同一个文件中检索多个 NDJSON 对象?

c++ - constexpr 中的构建错误

c++ - SQLite C++ 'database is locked' 当多个进程以只读模式访问数据库时