1. A method comprising: initiating execution of a plurality of threads to process instructions of a program that includes a barrier instruction; for each thread in the plurality of threads, pausing execution of instructions when the thread reaches the barrier instruction; determining that the barrier instruction may be scheduled for execution when either a maximum duration of time has transpired or a minimum number of participating threads that is less than a number of threads that participate in the barrier instruction have reached the barrier instruction; associating a first sub-group of the threads in the plurality of threads with a first sub-barrier index; associating a second sub-group of the threads in the plurality of threads with a second sub-barrier index; and executing threads in the first sub-group serially and executing threads in the second sub-group serially, wherein at least one thread in the first sub-group is executed in parallel with at least one thread in the second sub-group.