Deal with prices as an int not a float. This important as the price can then form the key of a hash table. Size of the hash table should be the limits of price in your book (including decimal places you support). This seems like a lot of memory, however the structures we're dealing with are small. Insertion into the book is then largely O(1) as few people bid/offers are exactly the same price.
Bid and offer can share the same hash table as they will be at opposite ends of the table (apart from orders that cross).
We can preallocate all active orders and form a link list of nodes inside the order book. Never allocate any memory on the fly as it is very expensive.
Order { Order *next; int price; int size; int side; }
This will allow fast insertion/removal and will keep a lot of the data in the level 2 cache. Of course you need to keep the list big enough to support all active orders.
Processing an order would involve working out if it's a buy or sell, then hashing the price, if a value exists at that key you fill the order (or partial fill).
Finally use taskset or something similar to make sure the OS puts your process on a dedicated hardware thread.