Skip to content

Instantly share code, notes, and snippets.

@vmxdev
Last active September 11, 2019 13:18
Show Gist options
  • Select an option

  • Save vmxdev/31c377f55d6717fce86c3b1160c89017 to your computer and use it in GitHub Desktop.

Select an option

Save vmxdev/31c377f55d6717fce86c3b1160c89017 to your computer and use it in GitHub Desktop.
Atomics vs ordinary variables
/*
* Compile:
* $ gcc -O3 -g -Wall -pedantic -Wextra atest.cc -o atest -lstdc++ -pthread
*/
#include <atomic>
#include <cinttypes>
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdlib>
const static size_t N = 8;
std::uint32_t *raw_arr;
std::atomic<std::uint32_t> *atomic_arr;
volatile int stop = 0;
void
producer_fffuuu()
{
while (!stop) {
__asm__ __volatile__ ("" : : : "memory");
for (size_t i=0; i<N; i++) {
raw_arr[i] = raw_arr[i] + 1;
}
}
}
void
producer_good()
{
while (!stop) {
for (size_t i=0; i<N; i++) {
atomic_arr[i].store(
atomic_arr[i].load(std::memory_order_relaxed)
+ 1,
std::memory_order_relaxed);
}
}
}
void
consumer()
{
while (!stop) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
for (size_t i=0; i<N; i++) {
std::cout << raw_arr[i] << " ";
}
std::cout << std::endl;
for (size_t i=0; i<N; i++) {
std::cout
<< atomic_arr[i].load(std::memory_order_relaxed)
<< " ";
}
std::cout << std::endl << std::endl;
}
}
int
main()
{
std::thread pf, pg, c;
raw_arr = static_cast<std::uint32_t *>(
aligned_alloc(128, N * sizeof(std::uint32_t)));
atomic_arr = static_cast<std::atomic<std::uint32_t> *>(
aligned_alloc(128, N * sizeof(std::atomic<std::uint32_t>)));
for (size_t i=0; i<N; i++) {
raw_arr[i] = 0;
atomic_arr[i] = {0};
}
pf = std::thread(producer_fffuuu);
pg = std::thread(producer_good);
c = std::thread(consumer);
std::this_thread::sleep_for(std::chrono::seconds(2));
stop = 1;
pf.join();
pg.join();
c.join();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment