Did you try disabling object lock wait timing? And if so, did you see a noticeable drop in cpu utilization?
64 dataserver engines still sounds like a LOT of resources for just 800 users ... though it's hard to tell without a more thorough analysis of your dataserver's load during all periods of a typical work week (not to mention any occasional surges in activity, eg, EOM/EOQ processing).
----------------
You've got a single log bound to the workdb_log cache (this is good; the log activity doesn't conflict with cache activity on another objects).
The transaction log is basically a heap with any/all contention on the last log page, so multiple cache partitions will do nothing for the last-log-page contention. In fact, multiple partitions in the log can lead to fragmenting the log amongst the cache partitions which can require excessive cache-related processing by various processes.
I'd reduce partitions (in the workdb_log cache) to 1. And since the tran log is the only thing bound to this cache (again, this is good), and the database's logiosize is 16K, this means the 8K pool is basically unused ... so I'd shift as much of the memory from the 8K pool to the 16K pool (eg, you'll have to leave 5-10MB in the 8K pool since you can't eliminate the 8K pool altogether), This should give you a single, monolithic chunk of 5100MB in the workdb_log, which in turn should reduce amount of disk activity ... AS LONG AS total log space usage doesn't get above 5GB.
----------------
As for the disk mirroring ... you're not using it, it does incur some overhead, so disable it (disable disk mirroring = 1; requires a reboot of the dataserver).