пятница, 30 июля 2010 г.

OpenMP: простой пример параллелизации вычислений.

В Visual Studio 2005 необходимо включить поддержку OpenMP, после чего можно запустить такой простой пример (перемножение матриц):
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QTime>
#include "omp.h"

int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);

 int ii, jj, kk;
 const int dim = 1000;
 int * arr = new int[dim*dim];
 int * arr1 = new int[dim*dim];
 int * arr2 = new int[dim*dim];

 QTime time;
        time.start();

 for (ii = 0; ii < dim; ii++) {
  for (jj = 0; jj < dim; jj++) {
   for (kk = 0; kk < dim; kk++) {
    arr[ii, jj] = arr1[ii, kk] * arr2[kk, jj];
   }
  }
 }

 qDebug() << QString("Without OpenMP, time %1 sec").arg((double)time.elapsed()/1000);

 time.restart();

 #pragma omp parallel for shared(arr, arr1, arr2, dim) private(ii, jj, kk)
 for (ii = 0; ii < dim; ii++) {
  for (jj = 0; jj < dim; jj++) {
   for (kk = 0; kk < dim; kk++) {
    arr[ii, jj] += arr1[ii, kk] * arr2[kk, jj];
   }
  }
 }

 qDebug() << QString("With OpenMP, time %1 sec").arg((double)time.elapsed()/1000);

 delete [] arr;
 delete [] arr1;
 delete [] arr2;


 return a.exec();
}

Colored with dumpz.org


То есть перемножали матрицу без использования OMP и с использованием OMP. На выходе было (E7400 2.8GHZ):

"Without OpenMP, time 5.406 sec"
"With OpenMP, time 2.734 sec"

Результаты говорят сами за себя. Особо важно заметить, что в данном случае каждый элемент результирующей матрицы может быть вычислен независимо от любого другого элемента, именно это и дает возможность распараллеливания.

Тут можно почитать об этом чуть подробнее:
http://software.intel.com/ru-ru/articles/getting-started-with-openmp/

понедельник, 5 июля 2010 г.

Чтение с помощью STL

Очень интересный пример чтения файла с помощью STL:
http://easy-coding.blogspot.com/2009/02/stl.html

Любопытно скорость чтения последними двумя способами:

TEST(ReaderTest, istreambuf_iterator_tostring_short) {
  std::string v(
    (std::istreambuf_iterator<char>(
      std::ifstream(Env::testfile())
    )), 
    std::istreambuf_iterator<char>()
  );

  EXPECT_EQ(Env::testfile_sz(), v.length()); 
}


TEST(ReaderTest, istreambuf_iterator_tostring_short_auto_ptr) {
  std::string v(
    (std::istreambuf_iterator<char>(
      *(std::auto_ptr<std::ifstream>(
        new std::ifstream(Env::testfile())
      )).get()
    )), 
    std::istreambuf_iterator<char>()
  );

  EXPECT_EQ(Env::testfile_sz(), v.length()); 
}

Colored with dumpz.org


Если в VS2005 запускать без оптимизации, то каждый из этих двух тестов выполняется за 125 мс, а с оптимизацией - за 31 мс. То есть имеем четырехкратный прирост производительности.