Консультация № 140945
29.07.2008, 05:22
0.00 руб.
0 1 1
Уважаемые Эксперты, у мезя задача в увеличении скорости работы моих программ, перешел с VS 6 (2000) на VS 2005 и посему первый вопрос:

Cofiguration properties-C/C++-opttimization-maximzeSppeed(/O2) не знаю где установить O2 и посему получаю глобальную ошибку
1>cl : Command line error D8016 : '/O1' and '/RTC1' command-line options are incompatible
1>Build log was saved at "file://c:Documents and SettingsAleksanderМои документыVisual Studio 2005ProjectssungensungenDebugBuildLog.htm"
1>sungen - 1 error(s), 0 warning(s)
и стоит ли с этим связываться?

Теперь главный вопрос о работы программы на двух процессорах ( у меня core 2 duo)
Структура программы такова – массивы общих данных определены перед main программой, а наибольшая глубина вычислений в вызываемой из неё подпрограммой которая используя глобальные данные рассчитывает и возвращает значение по 250 примерам.
#include "stdafx.h"

inline int ff();

глобальные данные
static unsigned short indat [271] [10]; // ??????? ??????
static unsigned short sout [5] [200];

int _tmain(int argc, _TCHAR* argv[])
{

f=ff(); расчет 250 примеров
}
int ff()
{
for (i=0; i<250; i++) {

}
return n;
}

Теперь что я хочу, но запутался в статьях (стар и слаб на аглицкий):
#include "stdafx.h"

inline int ff1();
inline int ff2();

глобальные данные
static unsigned short indat [271] [10]; // ??????? ??????
static unsigned short sout [5] [200];

int _tmain(int argc, _TCHAR* argv[])
{

f1=ff1(); расчет 0-124 пример в основном потоке
f2=ff2(); расчет 125-249 пример на втором процессоре f=f1+f2;
}

int ff1()
{
for (i=0; i<125; i++) {

}
return n;
}

int ff2()
{
for (i=125; i<250; i++) {

}
return n;
}
Что надо добавить в то что я хочу? (#include ……………..)
Спасибо, извините за возможно путанный вопрос?
С уважением Александр

Обсуждение

Неизвестный
29.07.2008, 09:40
общий
это ответ
Здравствуйте, Третьяченко Александр Сергееич!
Сначало по первому вопросу.
Настройки оптимизации находятся тут:
[Project Properties]/[Configuration Properties]/[C/C++]/[Optimization]/[Optimization] опции:
- Disabled (/Od)
- Minimize Size (/O1)
- Maximize Speed (/O2)
- Full Optimization (/Ox)
[Project Properties]/[Configuration Properties]/[C/C++]/[Code Generation]/[Basic Runtime Check] опции:
- Default
- Stack Frames (/RTCs)
- Uninitialized Variables (/RTCu)
- Both (/RTC1, equiv. to /RTCsu)
Несовместимость опций может быть вызвана противоречием в желании уменьшить размер и одновременно добавить код проверок времени исполнения (typeof, type_id и т.д.). Установка оптимизации размера программы, как мне кажется, морально устарела (объем НЖМД подрос, да и оперативной памяти обычно бывает вполне достаточно). Лучше ставить максимизацию скорости или полную оптимизацию.

По втрому вопросу. Как я понял, вы хотите ускорить время выполнения программы, задействовав оба процессора. Тут возможно 2 пути.
Первый заключается в использовании специализированного компилятора (от Intel), который сам выполняет распараллеливание кода, и оптимизирует его на исполнение на многопроцессорных (и многоядерных) системах.
Второй способ в меньшей степени зависит от компилятора и заключается в использовании нескольких потоков. Об этом способе расскажу подробней.
Каждая программа (процесс в системе) выполняется в 1 или нескольких потоках (thread). Потоки разделяют общую память процесса, но выполняются независимо друг от друга. Каждый поток может одновременно выполняться только на одном процессоре. Поэтому чтобы задействовать несколько процессоров, необходимо использовать несколько потоков. Подробнее про многопоточность можно прочитать по ссылке в приложении.
Для создания потока используется функция _beginthreadex (если и другие функции, но лучше использовать эту):
uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr);
Типичное использование:
#include <process.h>
...
unsigned RunFunc(void* arg); // функция потока
...
unsigned idThread; // id потока
int arg = 5;
HANDLE hThread = (HANDLE)_beginthreadex(0, 0, RunFunc, &arg, 0, &idThread);
...
Функция создает поток и запускает в нем на исполнение указаную функцию (RunFunc), которй передает заданный аргумент (arg), который может быть, например, указателем.
Узнать о состоянии потока (исполняется или уже завершился) можно с помощью функции WaitForSingleObject:
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds);
Эта функция вернет будет ждать (dwMilliseconds миллисекунд) завершения потока и вернет константу WAIT_TIMEOUT, если истек таймаут ожидания, или досрочно вернет WAIT_OBJECT_0, если поток завершился.
Досрочно завершить поток можно с помощью функции TerminateThread:
BOOL TerminateThread(
HANDLE hThread,
DWORD dwExitCode);
В вашем, примере, можно часть вычислений выполнять в главном (первом) потоке, а для другой части создать дополнительный поток. Примерный код в приложении:
Так же почитайте хэлп по приведенным функциям.

Приложение:
// http://ru.wikipedia.org/wiki/Многопоточность

#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

// данные
static int data[250];

unsigned int __stdcall CalcFunc(void* arg)
{
int* n = (int*)arg;
int i;

// вычисления в отдельном потоке
*n = 0;
for (i = 125; i < 250; ++i)
{
*n += data[i];
}

_endthreadex(0);
return 0;
}

int main()
{
int i, n1, n2;
unsigned tid;
HANDLE h;
DWORD res;

// заполняем данные
for (i = 0; i < 250; ++i)
{
data[i] = rand();
}

// запускаем поток
// второй поток следует запустить перед началом вычислений
n2 = 0;
h = (HANDLE)_beginthreadex(0, 0, CalcFunc, &n2, 0, &tid);

// вычисления в основном потоке
n1 = 0;
for (i = 0; i < 125; ++i)
{
n1 += data[i];
}

// ждем окончания работы потока
res = WaitForSingleObject(h, 2000);
if (res == WAIT_TIMEOUT)
{
// насильно завершаем поток, он еще не досчитал
TerminateThread(h, 0);
CloseHandle(h);
printf("Process terminated");
}
else
{
// поток закончил вычисления и завершился
CloseHandle(h);
printf("Process finished");
}

// результаты
printf("%d + %d = %d", n1, n2, n1+n2);

return 0;
}
Форма ответа