Skip to content

Poor dsyrk performance on skylake using more than 1 threads #1115

Closed

Description

@thrasibule

I am getting poor performance for dsyrk when using more than 1 thread. My cpu is Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz, generation Skylake. Openblas defaults to using the haswell kernels.
I am looking at the perfomance of a simple X^T.dot(X) for X of size 1,000,000 by 100, using dsyrk and comparing it to dgemm for n=1 or 2 threads.

The performance numbers are summarized in the table below. They are time in s for 5 runs.

test Haswell Sandybridge
dsyrk(2 threads) 2.49 1.83
dgemm(2 threads) 2.09 2.86
dsyrk (1 thread) 2.60 3.13
dgemm (1 thread) 3.47 5.17

The numbers for target Sandybridge were run on the same machine, but by recompiling openblas and specifying TARGET=SANDYBRIDGE in the Makefile.

The second column numbers make sense: dsyrk is ~1.7 faster than dgemm, and we gain another 1.7 factor by doubling the number of threads. The haswell column is quite disappointing. dgemm seems to scale well, but dsyrk doesn't seem to scale at all with more than 1 thread, so that using dgemm with 2 threads is actually faster.

Has anybody observed something similar? I am wondering if this is related to #730, although I'm using linux. The script that I used to get those numbers is available here.

Activity

  1. brada4 commented on Mar 6, 2017

    @brada4
    Contributor

    Which version of OpenBLAS?
    Which operating system?
    ... Python ... Numpy ... CC ... ?
    Same dsyrk is used for sandy bridge and haswell which is created from same C source file by same your compiler. Do you have any explanation to measured difference?

  2. martin-frbg commented on Mar 6, 2017

    @martin-frbg
    Collaborator

    Same dsyrk is used for sandy bridge and haswell which is created from same C source file

    using (probably) differing cpu-specific constants from param.h to guide unrolling (b07d733 could be relevant) and using different assembly implementations of xGEMM to do the actual work...

  3. thrasibule commented on Mar 6, 2017

    @thrasibule
    ContributorAuthor

    @brada4, this is with latest master on Linux. I've posted a link to the script I used to generate the numbers in the first post. I'm reposting it here I'm using numpy to call blas, but that shouldn't matter.

  4. martin-frbg commented on Mar 8, 2017

    @martin-frbg
    Collaborator

    This may be a silly question, but have you checked if your test script is actually running on more than one core ?

  5. thrasibule commented on Mar 8, 2017

    @thrasibule
    ContributorAuthor

    This is not a silly question at all, I think you're onto something! I have two cores with multithreading. If I do nothing, openblas will use 4 threads, but if I usually force it to 2, because the performance is slightly better.
    But with latest master, dsyrk will only use 1 thread if I run it with OMP_NUM_THREADS=2, and 2 threads if OMP_NUM_THREADS=4. That explains the numbers that I reported, with dsyrk not being faster for 2 threads, I needs to use 4.
    Now on a whim, I tried to revert b07d733 which you said might be relevant, and the behavior is more logical, with dsyrk using 2 threads if I set OMP_NUM_THREADS=2, and 4 if I set OMP_NUM_THREADS=4, which matches with how dgemm behaves. Performance is actually slightly better too, but that might be some measurement error.
    Let me know if this makes sense. I don't understand what the rationale behind b07d733 is, so this is just poking in the dark for me. I can run more tests if that helps.

  6. martin-frbg commented on Mar 8, 2017

    @martin-frbg
    Collaborator

    While I obviously cannot speak for wernsaar, it could be that the code was optimized for a different workload (your matrix size might be close to the number where he observed threading overhead to be greater than parallelization advantage). As an aside I am having problems trying to replicate your results on my i7-7500U at the moment - could be a hardware issue (or a borked numpy shipped with the distribution) as my timings from your script are on the order of 30 to 60 seconds.

  7. martin-frbg commented on Aug 1, 2017

    @martin-frbg
    Collaborator

    Returning to this old issue, another factor may have been that - as was discovered in #1232 - until very recently the cpuid code misdetected the L1 cache on Haswell and later generation Intel chips as only a quarter of the actual size.

  8. added this to the 0.3.6 milestone on Dec 31, 2018
  9. modified the milestones: 0.3.6, 0.3.7 on Apr 27, 2019
  10. modified the milestones: 0.3.7, 0.3.8 on Aug 11, 2019
  11. h-vetinari commented on Nov 6, 2019

    @h-vetinari
    Contributor

    @thrasibule
    Could you rerun the perf tests with latest master? There's been a bunch of changes to the skylake code, compare some of the merged PRs.

  12. martin-frbg commented on Nov 6, 2019

    @martin-frbg
    Collaborator

    @h-vetinary the recent changes you mention are for "Skylake X" which is high-end Xeon with AVX512 - this ticket is about older i7-6xxx hardware

  13. martin-frbg commented on Nov 6, 2019

    @martin-frbg
    Collaborator

    @h-vetinary the recent changes you mention are for "Skylake X" which is high-end Xeon with AVX512 - this ticket is about older i7-6xxx hardware

  14. 1 remaining item

  15. martin-frbg commented on Nov 6, 2019

    @martin-frbg
    Collaborator

    Blame Intel for the confusing names - "Skylake X" or "Skylake Xeon" has AVX512 support which all the recent troubles and improvements in the "Skylake X" area was about, plain "Skylake" is just another slightly improved Haswell refresh in between "Broadwell" and "Kaby Lake". The issue here is "just" that a change appears to have been made than favors one kind of workload over another,
    and the person who contributed this change stopped contributing (or even responding) at around the same time that this was brought up.

  16. modified the milestones: 0.3.8, 0.3.9 on Feb 5, 2020
  17. david-cortes commented on Feb 15, 2020

    @david-cortes
    Contributor

    Comment: the issue also affects AMD Ryzen 7 2700.

  18. modified the milestones: 0.3.9, 0.3.10 on Mar 1, 2020
  19. modified the milestones: 0.3.10, 0.3.11 on Jun 14, 2020
  20. martin-frbg commented on Oct 15, 2020

    @martin-frbg
    Collaborator

    Pushing the milestone again but have confirmed that the introduction of the GEMM_UNROLL_MN for Haswell (with subsequent inheriting by newer generations) slows down both syrk and gemm at this problem size (at least). Best results when the parameter is removed (which gives a value of 8, compared to 16 before the dubious #747) and the additional condition for >= 2 * GEMM_UNROLL_MN as well. I notice wernsaar apparently made that change in response to, but without commenting on, #730 which may have been affected by an OSX-specific issue (mishandled aligns in the assembly kernels) and additionally was about single-thread performance.

  21. modified the milestones: 0.3.11, 0.3.12, 0.3.13 on Oct 15, 2020
  22. martin-frbg commented on Dec 11, 2020

    @martin-frbg
    Collaborator

    fixed by reverting #747 in #3026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions