2

I have 6 functions:

  • fetch operation
  • decode
  • fetch operands
  • execute
  • writeback
  • updatepc

Each giving input to another. I want to execute them at the same time i.e., pipelining.

How to do that?

Jops
  • 22,535
  • 13
  • 46
  • 63
user2262755
  • 23
  • 1
  • 1
  • 4

3 Answers3

2

Pipeline Pattern

Pipeline Pattern is helpful in dividing the problem into smaller reusable code components. This is a simple yet powerful structural pattern to organize a complex logic into smaller reusable components, which can be added/removed/modified independently.

Achintya Jha
  • 12,735
  • 2
  • 27
  • 39
2

Create a class for each pipeline component that implements Runnable. Give each component a ConcurrentLinkedQueue to hold the data to be processed; each component will poll this queue in an infinite loop (in its run() method), processing the data as it pulls it off. Each preceding component will add its output to the next component's queue. Now assign each runnable to a thread, start the threads, and start feeding data to the first component's queue.

If a component finds that its queue is empty then you may want to put it to sleep for half a second or so.

You may also want to add a cancel() method to each component that will break out of the infinite loop in its run() method.

public class Decode implements Runnable {
   private boolean cancel = false;
   private ConcurrentLinkedQueue<Data> queue = new ConcurrentLinkedQueue<>();
   private FetchOperands nextComponent;

   public void run() {
       while(!cancel) {
           Data data = queue.poll();
           if(data != null) {
               ...
               nextComponent.enqueue(data);
           } else (Thread.sleep(500);
       }
   }

   public void enqueue(Data data) {
       queue.offer(data);
   }

   public void cancel() {
       cancel = true;
   }

   public void setFetchOperands(FetchOperands nextComponent) {
       this.nextComponent = nextComponent;
   }
}

public class Main implements Runnable {
    public void run() {
        Decode decode = new Decode();
        FetchOperands fetchOperands = new FetchOperands();
        decode.setFetchOperands(fetchOperands);
        Thread t1 = new Thread(decode);
        Thread t2 = new Thread(fetchOperands);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}
Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • Thank you very very much I will try this.One more question.The queue in your example,is declared in decode class and it is set private.Will it be visible to other classes to poll data(Am i making sense)?. – user2262755 Apr 09 '13 at 17:10
  • The queue is going to be invisible to other objects, because you only want other objects to be able to add data to the queue, not to remove data from the queue. The preceding component, in this case the FetchOperation component, should have a reference to the Decode component, and should call the Decode component's enqueue method in order to pass data along the pipeline. – Zim-Zam O'Pootertoot Apr 09 '13 at 17:12
1

To improve upon @Zim-Zam O'Pootertoot's answer, instead of having your component sleep for a little when there is nothing to process, you could have it wait(), and then call notify() whenever you pass it something to process.

Community
  • 1
  • 1
sep1256
  • 55
  • 6