[Python] Python, numpy and the cacheline

Discussão em 'Python' iniciado por Stack, Setembro 27, 2024.

  1. Stack

    Stack Membro Participativo

    I try to follow https://igoro.com/archive/gallery-of-processor-cache-effects/ in python using numpy. Though it does not work and I don't quite understand why...

    numpy has fixed size dtypes, such as np.int64 which takes up 8 bytes. So with a cacheline of 64 bytes, 8 array values should be held in cache.

    Thus, when doing the timing, I should not see a notable change in required time when accessing values within the cacheline, because the same number of cache line transfers are needed.

    Based on this SO answer, I also tried to disable the garbage collection which didn't change anything.

    # import gc
    import time
    import numpy as np

    def update_kth_entries(arr, k):
    arr[k] = 0
    start = time.perf_counter_ns()
    for idx in range(0, len(arr), k):
    arr[idx] = 0
    end = time.perf_counter_ns()
    print(f"Updated every {k:4} th entry ({len(arr)//k:7} elements) in {(end - start)*1e-9:.5f}s")
    return arr

    # gc.disable()
    arr = np.arange(8*1024*1024, dtype=np.int64)
    print(
    f"(Data) size of array: {arr.nbytes/1024/1024:.2f} MiB "
    f"(based on {arr.dtype})"
    )

    for k in np.power(2, np.arange(0,11)):
    update_kth_entries(arr, k)
    # gc.enable()


    This gives something like

    (Data) size of array: 64.00 MiB (based on int64)
    Updated every 1 th entry (8388608 elements) in 0.72061s
    Updated every 2 th entry (4194304 elements) in 0.32783s
    Updated every 4 th entry (2097152 elements) in 0.14810s
    Updated every 8 th entry (1048576 elements) in 0.07622s
    Updated every 16 th entry ( 524288 elements) in 0.04409s
    Updated every 32 th entry ( 262144 elements) in 0.01891s
    Updated every 64 th entry ( 131072 elements) in 0.00930s
    Updated every 128 th entry ( 65536 elements) in 0.00434s
    Updated every 256 th entry ( 32768 elements) in 0.00234s
    Updated every 512 th entry ( 16384 elements) in 0.00129s
    Updated every 1024 th entry ( 8192 elements) in 0.00057s


    Here is the output of lscpu -C

    NAME ONE-SIZE ALL-SIZE WAYS TYPE LEVEL SETS PHY-LINE COHERENCY-SIZE
    L1d 32K 384K 8 Data 1 64 1 64
    L1i 32K 384K 8 Instruction 1 64 1 64
    L2 256K 3M 4 Unified 2 1024 1 64
    L3 16M 16M 16 Unified 3 16384 1 64


    At this point I am quite confused about what I am observing.

    • On the one hand I fail to see the cacheline using above code.
    • On the other hand I can show some sort of CPU caching effect using something like in this answer with a large enough 2D array.

    I did above tests in a container on a Mac. A quick test on my Mac shows the same behavior.

    Is this odd behavior due to the python interpreter?

    What am I missing here?

    Continue reading...

Compartilhe esta Página