2015-06-12 1 views
2

Say я 2 сессии подписанная:Параллельная обработка в SAS, ждет бесплатных сеансов

signon slave1; 
signon slave2; 

Скажем, у меня есть 10 заданий, выполняемых

%execute_job(parameter= 1); 
%execute_job(parameter= 2); 
%execute_job(parameter= 3); 
. 
. 
. 
%execute_job(parameter= 10); 

Что мне нужно сделать, чтобы добавить в% execute_job так что он будет продолжать ждать бесплатного сеанса и отправить задание на первый свободный сеанс, который он найдет?

Я попробовал вещи в макваре безрезультатно.

+0

Разве это не означает, что 'waitfor _any_' специально разработан? – Joe

+0

Даже с waitfor _any_, мы все еще имеем проблему выяснения того, какие рабы свободны и назначить задание этому конкретному ведомому. В этом суть проблемы. Решение, которое я нашел, и что vasja рекомендуется, состоит в том, чтобы иметь какое-то соглашение об именах для cmacvar. Это действительно не идеально. В openmp C++ или что-то еще, все, что вам нужно сделать, это сказать «динамическое планирование», и все это будет правильно обработано для вас. Я не знаю, почему это не реализовано в SAS. – Matt

ответ

1

Хорошо, я думаю, что есть кое-что:

options sascmd="!sascmd"; 


%macro job(value); 

    %local slave_id; 

    %let slave_id = 1; 

    %do %while(&&slave&slave_id.); 
     %put Slave&slave_id. is busy and cannot be assigned job; 

     %if &slave_id. < 2 %then 
      %let slave_id = %eval(&slave_id. + 1); 
     %else 
      %let slave_id = 1; 
    %end; 

    %put Slave&slave_id. is free and is assigned job; 

    %syslput _user_ /remote= slave&slave_id.; 

    rsubmit slave&slave_id. macvar=slave&slave_id. wait=no; 


     data _null_; 

      file print; 
      put "&value. by &slave_id.!"; 

     run; 

    endrsubmit; 

%mend job; 

signon slave1 macvar=slave1; 
signon slave2 macvar=slave2; 

%job(6); 

%job(7); 

%job(8); 

signoff slave1; 
signoff slave2; 
+2

Ваш цикл '% do% while' будет бесполезным сжиганием большого количества процессора - я бы посоветовал вам поспать там. – user667489

+0

Да, или «waitfor _any_», в конце первого поиска через ведомые устройства. Мне нужно проверить это. – Matt

3

Рассмотрим это: Я использую cmacvar опцию входа в систему, чтобы выделить локальный вар макрос для статуса удаленного сеанса. В syslput я создал удаленный my_id макрос var на обоих подчиненных, чтобы они знали «кто они».

Тогда у меня есть% job macro получение ID slave для запуска некоторого кода. Для реального мира также должен быть некоторый параметр работы. Здесь я просто имитирую более короткое job1 и более длинное job2.

В% run_jobs Я делаю несколько циклов, чтобы попытаться запустить подчиненные несколько раз. Главное, что вы делаете в WAITFOR _ANY_.

signon slave1 sascmd="!sascmd" cmacvar=slave1; 
signon slave2 sascmd="!sascmd" cmacvar=slave2; 

%syslput my_id=1 /remote=slave1; 
%syslput my_id=2 /remote=slave2; 

rsubmit slave1; 
options nomprint nosource nonotes; 
endrsubmit; 
rsubmit slave2; 
options nomprint nosource nonotes; 
endrsubmit; 
/* 
my_id is remote 
slave_id is local 
*/; 
%macro job(slave_id); 
rsubmit slave&slave_id. wait=no; 
    data _null_; 
     %if &slave_id eq 2 %then %do; 
      x = sleep(2); 
     %end; 
     x = sleep(4); 
     s = put(DATETIME(), DATETIME.) || " at &my_id.!"; 
     putlog s; 
    run; 
endrsubmit; 
%mend; 


%macro run_jobs; 
    %do i=1 %to 4; 
     %if &slave1 eq 0 %then %do; 
      %put Slave1 starting; 
      %job(1) 
     %end; 
     %else %put Slave1 working; 
     %if &slave2 eq 0 %then %do; 
      %put Slave2 starting; 
      %job(2) 
      %put Slave2: &slave2; 
     %end; 
     %else %put Slave2 working; 
     WAITFOR _any_ slave1 slave2; 
     *LISTTASK _ALL_ ; 
     %put at end of loop &i:; 
     %put Slave1: &slave1; 
     %put Slave2: &slave2; 
    %end; 
%mend; 


options nomprint nosource nonotes; 
%run_jobs 

signoff slave1; 
signoff slave2; 
+0

Мне нужно попробовать это, когда я получу SAS в понедельник! – Matt

Смежные вопросы