Hi!
I am new to multi-threading in SAS. I know the table is locked if editing a table but is it possible to read (only) a table at the same time from multiple threads?
Thanks,
Have you looked at PROC DS2? Multithreading is baked in. See this blog post for an example.
The benefit is bigger when the process is CPU bound, not I/O bound. But if parallel processing is what you're after, DS2 is worth a look.
OK! Thanks. I will take a look at DS2.
In the meantime, to give you some context:
we are using ( rsubmit, signoff) to submit multiple threads. Each thread need to access exactly the same table for reading only. Currently we are duplicating each table multiple times for each thread. I was wondering if it is possible to not do this - just read the table directly from different threads at the same time.
I don't see why not...
For example, here's a program that we can run in 3 sessions:
proc means data=sashelp.cars(where=(Origin='Asia'));
run;
proc means data=sashelp.cars(where=(Origin='Europe'));
run;
proc means data=sashelp.cars(where=(Origin='USA'));
run;
For such a simple program this is a lot of overhead, but I used EG's Analyze Program feature to create a grid-ready version of the program:
/*----------------------------------------------------------------------------*/
/* There are 3 tasks in this job. */
/* 3 of these tasks can be RSUBMITed. */
/* These 3 tasks used 22 units of time. */
/* The longest task took 10 units of time, 45.5% of total time. */
/* Based on dependencies, a maximum of 3 tasks might run in parallel. */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* This is the user-modifiable number of connect sessions */
/*----------------------------------------------------------------------------*/
%let SCAPROC_SESSIONS_COUNT=3;
/*----------------------------------------------------------------------------*/
/* *** Please don't edit anything below this line. */
/* *** Regenerate the file if you need to make changes. */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Enable grid service */
/*----------------------------------------------------------------------------*/
%let rc=%sysfunc(grdsvc_enable(_all_, resource=SASMKT));
/*----------------------------------------------------------------------------*/
/* This macro starts up the connect sessions */
/*----------------------------------------------------------------------------*/
%macro scaproc_start_sessions(count);
%do i = 1 %to &count;
signon sess&i signonwait=no connectwait=no cmacvar=scaproc_signon_&i;
%end;
%mend scaproc_start_sessions;
/*----------------------------------------------------------------------------*/
/* Start up our connect sessions. */
/*----------------------------------------------------------------------------*/
%scaproc_start_sessions(&SCAPROC_SESSIONS_COUNT);
/*----------------------------------------------------------------------------*/
/* This function call initializes data structures for our SCAGRID functions. */
/* We pass in the number of sessions and the number tasks in this job. */
/*----------------------------------------------------------------------------*/
proc scaproc; startup 3 &SCAPROC_SESSIONS_COUNT; run;
/*----------------------------------------------------------------------------*/
/* TASK 1 run in rsubmit */
/*----------------------------------------------------------------------------*/
/* I/O Activity */
/*----------------------------------------------------------------------------*/
/* DATASET INPUT SEQ created in task 0 #C00003.CARS.DATA */
/*----------------------------------------------------------------------------*/
/* Symbol activity */
/*----------------------------------------------------------------------------*/
/* SYMBOL GET task:0 used by subsequent task:no Name:SYS_IOUSEEE */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMSTACKODS */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMTRACE */
/*----------------------------------------------------------------------------*/
/* ELAPSED 10 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Get an available session */
/*----------------------------------------------------------------------------*/
proc scaproc; getsession 1 "sess"; run;
%put sess=&sess;
/*----------------------------------------------------------------------------*/
/* rsubmit for task 1 */
/*----------------------------------------------------------------------------*/
rsubmit &sess sysrputsync=yes cmacvar=scagrid_task_1;
/* task 1 rsubmit */
proc means data=sashelp.cars(where=(Origin='Asia'));
run;
/* for incomplete steps */ ;run; quit; run;
endrsubmit;
/*----------------------------------------------------------------------------*/
/* TASK 2 run in rsubmit */
/*----------------------------------------------------------------------------*/
/* I/O Activity */
/*----------------------------------------------------------------------------*/
/* DATASET INPUT SEQ created in task 0 #C00003.CARS.DATA */
/*----------------------------------------------------------------------------*/
/* Symbol activity */
/*----------------------------------------------------------------------------*/
/* SYMBOL GET task:0 used by subsequent task:no Name:SYS_IOUSEEE */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMSTACKODS */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMTRACE */
/*----------------------------------------------------------------------------*/
/* ELAPSED 6 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Dependencies */
/* Highest task depended on: 0 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Get an available session */
/*----------------------------------------------------------------------------*/
proc scaproc; getsession 2 "sess"; run;
%put sess=&sess;
/*----------------------------------------------------------------------------*/
/* rsubmit for task 2 */
/*----------------------------------------------------------------------------*/
rsubmit &sess sysrputsync=yes cmacvar=scagrid_task_2;
/* task 2 rsubmit */
proc means data=sashelp.cars(where=(Origin='Europe'));
run;
/* for incomplete steps */ ;run; quit; run;
endrsubmit;
/*----------------------------------------------------------------------------*/
/* TASK 3 run in rsubmit */
/*----------------------------------------------------------------------------*/
/* I/O Activity */
/*----------------------------------------------------------------------------*/
/* DATASET INPUT SEQ created in task 0 #C00003.CARS.DATA */
/* FILE OUTPUT created in task 3 /sas/work/SAS_work038D0000658E_misci01p/#LN00023 */
/*----------------------------------------------------------------------------*/
/* Symbol activity */
/*----------------------------------------------------------------------------*/
/* SYMBOL GET task:0 used by subsequent task:no Name:SYS_IOUSEEE */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMSTACKODS */
/* SYMBOL GET task:0 used by subsequent task:no Name:SYSSUMTRACE */
/*----------------------------------------------------------------------------*/
/* ELAPSED 6 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Dependencies */
/* Highest task depended on: 0 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Get an available session */
/*----------------------------------------------------------------------------*/
proc scaproc; getsession 3 "sess"; run;
%put sess=&sess;
/*----------------------------------------------------------------------------*/
/* rsubmit for task 3 */
/*----------------------------------------------------------------------------*/
rsubmit &sess sysrputsync=yes cmacvar=scagrid_task_3;
/* task 3 rsubmit */
proc means data=sashelp.cars(where=(Origin='USA'));
run;
;*';*";*/;quit;run; /*Quote and Comment Killer*/
/* for incomplete steps */ ;run; quit; run;
endrsubmit;
/*----------------------------------------------------------------------------*/
/* This macro issues waitfors and signoffs for our sessions. */
/*----------------------------------------------------------------------------*/
%macro scagrid_waitfors(count);
%do i = 1 %to &count;
waitfor sess&i;
signoff sess&i;
%end;
%mend scagrid_waitfors;
/*----------------------------------------------------------------------------*/
/* Wait for and sign off all sessions. */
/*----------------------------------------------------------------------------*/
%scagrid_waitfors(&SCAPROC_SESSIONS_COUNT);
/*----------------------------------------------------------------------------*/
/* Termination for our SCAGRID functions. */
/*----------------------------------------------------------------------------*/
proc scaproc; shutdown; run;
/*----------------------------------------------------------------------------*/
/* All done. */
/*----------------------------------------------------------------------------*/
Thank you! I will try it.
Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.