TIL-4: Alignment


Alignment and Cache

  1. Common cache line size is 64 bytes

  2. To ensure data in different thread doesn’t interfere with other due to the requirement of cache consistency, we need to make sure they operate on data that is on different cache lines

  3. C++ provides us with keyword alignas
    1. alignas can be used to 1) the declaration or definition of a class; 2) the declaration of a non-bitfield class data member; 3) the declaration of a variable, except that it cannot be applied to the following: a function parameter; the exception parameter of a catch clause.
    2. Example: struct alignas(32) sse_t { ... }; or alignas(64) int x; or int alignas(64) x;
  4. C++ also provide hardware_destructive_interference_size and hardware_constructive_interference_size in <new>. According to cppreference, “these constants provide a portable way to access the L1 data cache line size.” 1
    1. hardware_destructive_interference_size defines “minimum offset between two objects to avoid false sharing.”
    2. hardware_constructive_interference_size defines “maximum size of contiguous memory to promote true sharing.”

        // occupies one cache line
        struct alignas(hardware_constructive_interference_size) OneCacheLiner {
            std::atomic_uint64_t x{};
            std::atomic_uint64_t y{};
        };
      
        // occupies two cache lines
        struct TwoCacheLiner {
            alignas(hardware_destructive_interference_size) std::atomic_uint64_t x{};
            alignas(hardware_destructive_interference_size) std::atomic_uint64_t y{};
        } twoCacheLiner;
      
  5. What exactly is alignment?
    1. “The number of bytes between successive addresses at which objects of this type can be allocated”
    2. “Each object type imposes its alignment requirement on every object of that type;”
    3. “The largest fundamental alignment of any type is implementation-defined and equal to the alignment of std::max_align_t” (which is the size of long double 16 bytes)
  6. alignof
    1. Like sizeof, but returned the alignment of the object

Trivia

  1. Shell command starts with spaces can hide this command from history

  2. A simplified evaluation order of shell (This is derived from one of our recent projects: Develop a Shell in Java)
    1. Command substitution is performed (see command substitution);
    2. The command is split into arguments based on whitespaces
    3. Globbing is performed
    4. The application is called
  3. Commonly used shortcuts for oh-my-zsh git plugin
    1. Cheatsheet
    2. ga = git add, gaa = git add -all
    3. gb = git branch, gbd = git branch -d, gbD = git branch -D
    4. gcb = git checkout -b, gco = git checkout, gd = git diff
    5. gf = git fetch, gfo = git fetch origin
    6. gl = git pull
    7. gp = git push, gpf = git push --force-with-lease, gpf! = git push --force
    8. gm = git merge
    9. gr = git remote, gra = git remote add
    10. grb = git rebase, grba = git rebase --abort, grbc = git rebase --continue, grbi = git rebase -i
  4. git reset different levels (soft, mixed, hard) 2
    1. Visualization of git reset different levels
  5. time command 3
    1. Real is wall clock time - time from start to finish of the call. This is all elapsed time including time slices used by other processes and time the process spends blocked (for example if it is waiting for I/O to complete).
    2. User is the amount of CPU time spent in user-mode code (outside the kernel) within the process. This is only actual CPU time used in executing the process. Other processes and time the process spends blocked do not count towards this figure.
    3. Sys is the amount of CPU time spent in the kernel within the process. This means executing CPU time spent in system calls within the kernel, as opposed to library code, which is still running in user-space. Like ‘user’, this is only CPU time used by the process.