Poor scaling

Avi Kivity avi@scylladb.com
Tue Aug 9 15:09:00 GMT 2016



On 08/09/2016 06:06 PM, David Smith wrote:
> On 08/09/2016 01:38 AM, Avi Kivity wrote:
>>
>> On 08/08/2016 06:00 PM, David Smith wrote:
>>> On 08/07/2016 07:47 AM, Avi Kivity wrote:
>>>> Running a process with 12 active threads, each bound to its own core,
>>>> and touching a systemtap array fairly frequently, I see:
>>>>
>>>>
>>>>     72.91%  scylla           [kernel.kallsyms]     [k] _raw_spin_lock
>>>>      3.49%  scylla           [kernel.kallsyms]     [k]
>>>> start_callback.isra.62
>>>>      1.77%  scylla           scylla                [.]
>>>> _ZSt13__adjust_heapIN9__gnu_cxx17__normal_iteratorIPPN8logalloc11region_implESt6vectorIS4_SaIS4_EEEElS4_NS0_5__ops15_Iter_comp_iterIZNS2_7tracker4impl15compact_on_idleERKSt8functionIFbvEEEUlS4_S4_E_EEEvT_T0_SM_T1_T2_.isra.437.constprop.582
>>>>
>>>>
>>>>      1.54%  scylla           [kernel.kallsyms]     [k] _raw_spin_unlock
>>>>      1.39%  scylla           scylla                [.]
>>>> _ZN7reactor10smp_pollfn4pollEv
>>>>      1.29%  scylla           libc-2.19.so          [.] epoll_pwait
>>>>      1.21%  swapper          [kernel.kallsyms]     [k] poll_idle
>>>>      1.06%  scylla           [kernel.kallsyms]     [k]
>>>> _raw_read_lock_irqsave
>>>>      1.01%  scylla           scylla                [.]
>>>> _ZSt11__push_heapIN9__gnu_cxx17__normal_iteratorIPPN8logalloc11region_implESt6vectorIS4_SaIS4_EEEElS4_NS0_5__ops14_Iter_comp_valIZNS2_7tracker4impl15compact_on_idleERKSt8functionIFbvEEEUlS4_S4_E_EEEvT_T0_SM_T1_T2_.isra.436.constprop.583
>>>>
>>>>
>>>>      0.80%  scylla           [kernel.kallsyms]     [k]
>>>> _raw_read_unlock_irqrestore
>>>>      0.78%  scylla           scylla                [.]
>>>> _ZN17smp_message_queue20flush_response_batchEv
>>>>      0.75%  scylla           [kernel.kallsyms]     [k]
>>>> utrace_report_syscall_entry
>>>>      0.63%  scylla           [kernel.kallsyms]     [k] task_utrace_struct
>>>>      0.50%  scylla           [kernel.kallsyms]     [k] native_read_tsc
>>>>      0.37%  scylla           [kernel.kallsyms]     [k]
>>>> utrace_report_syscall_exit
>>>>      0.32%  scylla           [kernel.kallsyms]     [k] delay_tsc
>>>>      0.28%  scylla           scylla                [.]
>>>> _ZN17smp_message_queue13process_queueILm2EZNS_16process_incomingEvEUlPNS_9work_itemEE_EEmRNS_8lf_queueET0_.isra.2371
>>>>
>>>>
>>>>      0.26%  scylla           scylla                [.]
>>>> _ZN17smp_message_queue13process_queueILm4EZNS_19process_completionsEvEUlPNS_9work_itemEE_EEmRNS_8lf_queueET0_.isra.2278
>>>>
>>>>
>>>>      0.20%  scylla           [kernel.kallsyms]     [k] _raw_spin_lock_irq
>>>>      0.18%  scylla           scylla                [.]
>>>> _ZN6memory9cpu_pages4freeEPv
>>>>      0.18%  scylla           liblz4.so.1.0.0       [.] LZ4_compress
>>>>      0.17%  scylla           scylla                [.]
>>>> _ZN7reactor9run_tasksER15circular_bufferISt10unique_ptrI4taskSt14default_deleteIS2_EESaIS5_EE
>>>>
>>>>
>>>>
>>>>
>>>> Now this is not something I can run to monitor a production load.
>>>>
>>>>
>>>> Is there any way I can improve scaling?
>>> It depends, we'd have to see your script to make suggestions.
>>>
>>
>> Here is the latest version of my script (I'm not sure whether tid() is a
>> process-local or global identifier, so I used a pid(), tid() pair).
> You shouldn't need to use the pair, both are unique systemwide. pid()
> returns the process group id (task->tgid) and tid() returns the thread
> id (task->pid). (The naming is an artifact of how process group ids
> where shoehorned into the linux kernel.)

I expected this to be the case but wasn't sure, the documentation is a 
bit terse.

>> #!/usr/bin/stap
>>
>> # usage: task_latency.stap process_name latency_threshold_ms
>>
>> global start_time
>>
>> probe process(@1).mark("reactor_run_tasks_single_start") {
>>      start_time[pid(), tid()] = gettimeofday_us()
>> }
>>
>> probe process(@1).mark("reactor_run_tasks_single_end") {
>>      delete start_time[pid(), tid()]
>> }
>>
>> probe timer.profile {
>>      if ([pid(), tid()] in start_time) {
>>          now = gettimeofday_us()
>>          start = start_time[pid(), tid()]
>>          if ((now - start) > $2 * 1000) {
>>              printf("detected tasks running for >%sms\n", @2)
>>              print_usyms(ubacktrace())
>>          }
>>      }
>> }
>>
>>
>> Are entire probes serialized, or just individual variables?  If the
>> latter, perhaps you can detect that an array's index is always tid(),
>> remove that index, and convert the global variable to a thread-local one
>> (with an exception for begin and end probes).
> The same probe handler can be running simultaneously in different
> threads. Probe handlers (and probe local variables) aren't really
> serialized. However, global variable access is serialized.

Cool, so the trick I suggested would work well.



More information about the Systemtap mailing list