Добро пожаловать в сеть Intel® Software Network вход | зарегистрироваться | помощь |
Поиск в форумах и блогах Intel® Software Network
в Вперед

Threading Building Blocks

Последнее сообщение 12-06-2007, 18:20 размещено MAD\akukanov. Ответов - 8.
Сортировать сообщения: Назад Вперед
 10-27-2007, 16:56 30220895  

Threading Building Blocks


Где можно почитать на русском?
Может быть подбор статей есть.
На англиийском информации много, просто нужен
перевод, боюсь с терминами запутаться
 
 10-30-2007, 15:29 30220899 в ответ на30220895  

На: Threading Building Blocks

Ефим, боюсь, что русскоязычных материалов по TBB просто нет. Программный продукт относительно новый, популярность в России не приобрёл и внимание переводчиков не привлёк. А у нас нет ресурсов переводить даже документацию на все языки мира, нам код надо писать :)

Давайте так: вы читаете англоязычные материалы и со всеми вопросами и непонятками обращаетесь в этот форум. Я обещаю, что в меру собственного понимания я и мои коллеги поможем вам разобраться с использованием TBB.

Алексей Куканов


- Алексей Куканов
 
 11-01-2007, 8:39 30220900 в ответ на30220899  

На: Threading Building Blocks

TBB объектно ориентированая технология.
У меня получается так, что
например если нужно распаралелить объектный
код: TBB дает самое лучшее ускорение(по сравнениею OpenMP,Windows Threads).
Если код процедурного типа (на TBB нельзя создать процедур ) то он проигрывает OpenMP. Win Threads c большим отставанием.
Я проверял на перемножении матриц.
Верно ли что TBB быстрее работает с Оъектами?
И если да то как это добились?
 
 11-02-2007, 13:17 30220902 в ответ на30220900  

На: Threading Building Blocks

Ефим, использование объектов в TBB даже там, где подразумевается процедура (я имею в виду функторы, function objects, например, для представления тела цикла в parallel_for) - проектное решение, обусловленное самой задачей разработки библиотеки параллельных алгоритмов для широкого круга проблем. Если вы посмотрите на алгоритмы STL, вы найдёте там аналогичные решения.

Но утверждать, что TBB быстрее работает с объектами, чем XXX, и наоборот, отстаёт от XXX при использовании процедур, было бы неверно. Любую функцию можно обернуть в функтор, и хороший компилятор, возможно, вовсе выкинет промежуточный код функтора и непосредственно вызовет функцию. Скорее всего, дело в конкретном коде. Если хотите, пришлите/поместите в форум ваш код и результаты таймирования, я попробую разобраться в причинах разницы.

Кстати, перемножение матриц - простая, но далеко не самая подходящая проблема для тестирования производительности параллельных библиотек. На матрицах маленького размера выигрыша может не быть просто из-за отсутствия достаточного количества работы для параллельного исполнения. Вдобавок, соотношение вычислительных операций к операциям работы с памятью достаточно низкое, и рано или поздно пропускная способность шины станет ограничивать рост производительности. В-третьих, подобные задачи очень хорошо векторизуются компиляторами, что ещё больше снижает вышеупомянутое соотношение и увеличивает приемлемый grainsize. Но всё это относится, конечно же, к любому способу распараллеливания, не только к TBB.


- Алексей Куканов
 
 11-06-2007, 10:52 30220911 в ответ на30220902  

На: Threading Building Blocks

Компилятор Intel 9.1 VS 2005 cpu E4300
Вот объектный код matrix-matrix умножение
Вот результаты таймирования TBB (OOП)
N(размер) blocke range 2d ..... d
500 0,5 1,04
1000 4,798495 7,2
1500 17,946081 28,997598

OpenMp приблизительно теже результаты(в OOП).


А вот результаты таймирования OpenMP процедур
N serial OpenMP
500 0,337989 0,138717
1000 2,782681 1,098517
1500 9,130783 3,509462
2000 23,285746 8,798946
2500 42,278669 16,276304
код для них в листинге №2
По результатам выходит что процедурный код работает быстрее? Что скажете?
Можно ли на TBB добиться такого времени?
MKL в обоих случаях дает (метод класса или процедура)
MKL
500 0,059792
1000 0,456846
1500 1,524242
2000 3,594688 Как????(SSE+OpenMP+алгоритм?)

листинг №1
#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/blocked_range2d.h"
#include
#include
#include
#include

// Fuction that converts numbers form LongInt type to double type
double LiToDouble (LARGE_INTEGER x) {
double result =
((double)x.HighPart) * 4.294967296E9 + (double)((x).LowPart);
return result;
}

// Function that gets the timestamp in seconds
double GetTime() {
LARGE_INTEGER lpFrequency, lpPerfomanceCount;
QueryPerformanceFrequency (&lpFrequency);
QueryPerformanceCounter (&lpPerfomanceCount);
return LiToDouble(lpPerfomanceCount)/LiToDouble(lpFrequency);
}
class MMM
{
double* pAMatrix; // The first argument - initial matrix
double* pBMatrix; // The second argument - initial
double* pCMatrix; // Result vector for multiplication
size_t Size; // Sizes of initial matrix
public:
MMM(size_t N )
{
Size=N;
pAMatrix=(double *) malloc (Size*Size*sizeof(double));
pBMatrix=(double *) malloc (Size*Size*sizeof(double));
pCMatrix=(double*) malloc (Size*Size*sizeof(double));
this->DummyDataInitialization();
}
~MMM()
{
................
}


void operator() ( const blocked_range& r )
const
{
int i, j, k; // Loop variables
for (size_t i = r.begin(); i {
for (j=0; j for (k=0; k pCMatrix[i*Size+j] += pAMatrix[i*Size+k]*pBMatrix[k*Size+j];
}


}
// Parallel block matrix mutiplication
void operator()( const blocked_range2d& r ) const
{

for( size_t i=r.rows().begin(); i!=r.rows().end(); ++i )
{
for( size_t j=r.cols().begin(); j!=r.cols().end(); ++j )
{
float sum = 0;
for( size_t k=0; k sum += pAMatrix[i*Size+k]*pBMatrix[k*Size+j];
pCMatrix[i*Size+j] = sum;
}
}
}

void BlocksParallelResultCalculation ()
{
int BlockSize = 125;
int GridSize = int (Size/double(BlockSize));
for (int n=0; n#pragma omp parallel for
for (int m=0; m for (int iter=0; iter for (int i=n*BlockSize; i for (int j=m*BlockSize; j for (int k=iter*BlockSize; k pCMatrix[i*Size+j] += pAMatrix[i*Size+k] * pBMatrix[k*Size+j];
}
void ParallelResultCalculation()
{
int i,j,k;
#pragma omp parallel for private (j, k)
for (i = 0; i {
for (j=0; j for (k=0; k pCMatrix[i*Size+j] += pAMatrix[i*Size+k]*pBMatrix[k*Size+j];

}
}
void MKL()
{
int i, j, k;
int incx,incy,beta;
double alpha=1,betta=0;
incx=1;
incy=1;
beta=0;
cblas_dgemm(CblasColMajor,CblasNoTrans,CblasNoTrans,Size,Size,Size,alpha,pAMatrix,Size,pBMatrix,Size,beta,pCMatrix,Size);
}


private:
void RandomDataInitialization()
{
size_t i, j; // Loop variables
srand(unsigned(clock()));
for (i=0; i {
for (j=0; j {
pAMatrix[i*Size+j] = rand()/double(1000);
pBMatrix[i*Size+j]= rand()/double(1000);
}
}
}
void DummyDataInitialization ()
{
size_t i, j; // Loop variables
for (i=0; i {
for (j=0; j {
pAMatrix[i*Size+j] = i;
pBMatrix[i*Size+j] = i;
}
}
}
};


int main()
{
double Start, Finish, Duration;
int N;
task_scheduler_init init;
printf("TBB matrix - matrix product");
printf("\n Size = ");
scanf("%d",&N);

MMM tmp(N);
int BlockSize = 125;
int GridSize = int (N/double(BlockSize));
Start=GetTime();
parallel_for( blocked_range2d(0, N, N/2, 0, N, N/2),tmp );
// parallel_for(blocked_range(0,N),tmp );
//tmp.ParallelResultCalculation();
//tmp.BlocksParallelResultCalculation();
// tmp.MKL();
Finish=GetTime();
Duration=Finish-Start;
printf("\n Time of execution: %f\n", Duration);
tmp.~MMM();

cout getch();
return 0;
}


Листинг №2
процедура перемножения матриц, для процедурного кода другие процедуры не выложил. Блочный алгоритм
void ParallelResultCalculation (double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size) {
int iter;
int BlockSize = 125; //кэш 1MB
int GridSize = int (Size/double(BlockSize));
for (int n=0; n#pragma omp parallel for)
for (int m=0; mfor (iter=0; iterfor (int i=n*BlockSize; ifor (int j=m*BlockSize; jfor (int k=iter*BlockSize; kpCMatrix[i*Size+j] += pAMatrix[i*Size+k] * pBMatrix[k*Size+j];
}

Как бы вы измеряли производительность библиотек? (На каких задачах)
LU разложение?
Что если исключит все обращения к памяти,
те если перемножать матрицы малого размера 10*10, около 1000-3000 раз. Можно быть увереным что все матрицы находятся в кэш памяти и обращения к оперативке минимальны.
ИЗВИНИТЕ ЗА КОЛИЧЕСТВО ВОПРОСОВ!!!!!!!
 
 11-06-2007, 11:02 30220912 в ответ на30220911  

На: Threading Building Blocks

I feel sorry.
Некторые методы исказились до не узнаваемости.
Помоему если нажать кнопку цитировать
можно получить оригинал без искажений
 
 11-06-2007, 18:35 30220915 в ответ на30220911  

На: Threading Building Blocks

Нет, при цитировании сообщения код ничуть не лучше. Попробуйте добавить архив с кодом как вложение.


- Алексей Куканов
 
 11-29-2007, 11:54 30220965 в ответ на30220915  

На: Threading Building Blocks

Измерение производительности, как я понимаю,
осуществяют при помощи LU разложения.
1) На сколько это адекватное измерение?
2) Почему LU ??
3) Где можно найти исходники тестов для измерения производительности, на которые можно сослаться??? или которые является стандартными???

 
 12-06-2007, 18:20 30220974 в ответ на30220965  

На: Threading Building Blocks

EfimSergeev:
Измерение производительности, как я понимаю, осуществяют при помощи LU разложения. 1) На сколько это адекватное измерение? 2) Почему LU ?? 3) Где можно найти исходники тестов для измерения производительности, на которые можно сослаться??? или которые является стандартными???

Ефим, у Вас столько вопросов, и они несколько сумбурно изложены... :) Я попытаюсь ответить, но не удаляемся ли мы от TBB как изначальной темы?

- Да, LU-разложение используется в измерении производительности. В частности, именно его вычисляет известный тест Linpack, используемый для тестирования пиковой производительности компьютеров и кластеров, на основе результатов которого строится список наиболее мощных вычислительных систем мира Top 500.

- Почему LU? Не знаю точно, но судя по Linpack, предположил бы, что алгоритм позволяет выжать из типичных современных систем производительность, близкую к пиковой.

- Linpack - лишь один из множества используемых тестов. Есть SPECOMP, SPECHPG, NAS benchmarks, EPCC и др. В принципе, любое вычислительноёмкое приложение в некотором смысле тест на производительность :) Более-менее полную картину можно получить, только собрав данные множества тестов. Можно также попытаться написать относительно простой тест, который моделирует поведение интересующего приложения, и использовать его.

- Исходники "промышленных" тестов вряд ли лежат в открытом доступе. SPEC ("спеки"), к примеру, точно надо покупать.

EfimSergeev:
Что если исключит все обращения к памяти,
те если перемножать матрицы малого размера 10*10, около 1000-3000 раз.

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

Возвращаясь к Вашему изначальному утверждению о TBB, OpenMP, "объектном" и "процедурном" коде. Разница во времени, конечно, будет, но большая её часть, уверен, будет обусловлена особенностями самого кода, а не библиотеками. Особенно если разница в разы. Один и тот же код использовать не получится, правильно? А "трансляция" может быть сделана неоптимально.


- Алексей Куканов
 
Просмотреть как поток новостей RSS в XML

Ярлыки


Тег для данного сообщения

...

Теги сообщества

...