# Further Adventures With CAS Instructions And Micro Benchmarking

DevFeed: [Further Adventures With CAS Instructions And Micro Benchmarking](<https://devfeed.tech/articles/further-adventures-with-cas-instructions-and-micro-benchmarking-13630.md>)

Original publisher: [Read original article](<https://mechanical-sympathy.blogspot.com/2013/01/further-adventures-with-cas.html>)

Author: Martin Thompson (noreply@blogger.com)

Published: 2013-01-25T17:59:00Z

Content type: article

Language: en

Sources: [Mechanical Sympathy](<https://devfeed.tech/sources/mechanical-sympathy.md>)

Topics: [benchmarking](<https://devfeed.tech/topics/benchmarking.md>), [Hardware](<https://devfeed.tech/topics/hardware.md>), [intel](<https://devfeed.tech/topics/intel.md>), [x86](<https://devfeed.tech/topics/x86.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [assembly](<https://devfeed.tech/tags/assembly.md>), [benchmarking](<https://devfeed.tech/tags/benchmarking.md>), [cas](<https://devfeed.tech/tags/cas.md>), [hardware](<https://devfeed.tech/tags/hardware.md>), [intel](<https://devfeed.tech/tags/intel.md>), [java](<https://devfeed.tech/tags/java.md>), [latency](<https://devfeed.tech/tags/latency.md>), [performance](<https://devfeed.tech/tags/performance.md>), [techniques](<https://devfeed.tech/tags/techniques.md>), [x86](<https://devfeed.tech/tags/x86.md>)

## AI overview

This article revisits apparent CAS and LOCK instruction performance differences between Intel Sandy Bridge and Nehalem processors. It explains that the original microbenchmark partly measured fairness rather than throughput and examines alternative atomic-increment testing using lock xadd.

## Source excerpt

In a previous article I reported what appeared to be a performance issue with CAS/LOCK instructions on the Sandy Bridge microarchitecture compared to the previous Nehalem microarchitecture. Since then I've worked with the good people of Intel to understand what was going on and I'm now pleased to be able to shine some light on the previous results. I observed a small drop in throughput with the uncontended single-thread case, and an order-of-magnitude decrease in throughput once multiple threads contend when performing updates. This testing spawned out of observations testing Java Queue implementations and the Disruptor for the multi-producer case. I was initially puzzled by these findings because almost every other performance test I applied to Sandy Bridge indicated a major step forward for this microarchitecture. After digging deeper into this issue it has come to light that my tests have once again fallen fowl of the difficulties in micro-benchmarking. My test is not a good means of testing throughput and it is actually testing fairness in a roundabout manner. Let's revisit the code and work through what is going on. Test Code #include <time.h> #include <pthread.h> #include <stdlib.h> #include <iostream> typedef unsigned long long uint64; const uint64 COUNT = 500 * 1000 * 1000; volatile uint64 counter = 0; void* run_add(void* numThreads) { register uint64 value = (COUNT / *((int*)numThreads)) + 1; while (--value != 0) { __sync_add_and_fetch(&counter, 1); } } void* run_xadd(void*) { register uint64 value = counter; while (value < COUNT) { value = __sync_add_and_fetch(&counter, 1); } } void* run_cas(void*) { register uint64 value = 0; while (value < COUNT) { do { value = counter; } while (!__sync_bool_compare_and_swap(&counter, value, value + 1)); } } void* run_cas2(void*) { register uint64 value = 0; register uint64 next = 0; while (value < COUNT) { value = counter; do { next = value + 1; value = __sync_val_compare_and_swap(&counter, value, next); } while (value