| Issue |
208193
|
| Summary |
[Flang]Unformatted sequential I/O with -fconvert=big-endian is significantly slower than gfortran
|
| Labels |
|
| Assignees |
|
| Reporter |
3776-u2
|
The current main-branch version (23.0.0git) shows significantly lower I/O throughput than gfortran when endian conversion is enabled for unformatted sequential I/O.
Repeated measurements consistently show a large slowdown when `-fconvert=big-endian` is enabled. Although the exact runtime varies between executions, flang remains substantially slower than gfortran.
Compiler versions:
```
$ flang --version
flang version 23.0.0git (https://github.com/llvm/llvm-project.git ecdd6403fd213f90243a3d354d4db3483b89471f)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: .../llvm/aarch64/main-20260706-ecdd6403fd21/bin
Build config: +assertions
$ gfortran --version
GNU Fortran (GCC) 16.1.0
Copyright (C) 2026 Free Software Foundation, Inc.
```
Bootstrap build with following CMake options
```
-DCMAKE_BUILD_TYPE=Release
-DLLVM_LINK_LLVM_DYLIB=ON
-DLLVM_ENABLE_PROJECTS=mlir;clang;flang;lld
-DLLVM_ENABLE_RUNTIMES=compiler-rt;libunwind;libcxxabi;libcxx;flang-rt;openmp
-DLLVM_ENABLE_ASSERTIONS=ON
-DLLVM_USE_LINKER=lld
-DCMAKE_C_FLAGS=-march=armv8.2-a
-DCMAKE_CXX_FLAGS=-march=armv8.2-a
-DBUILTINS_CMAKE_ARGS=-DCMAKE_C_FLAGS=-march=armv8.2-a;-DCMAKE_CXX_FLAGS=-march=armv8.2-a;-DCMAKE_Fortran_FLAGS=-march=armv8.2-a
-DRUNTIMES_CMAKE_ARGS=-DCMAKE_C_FLAGS=-march=armv8.2-a;-DCMAKE_CXX_FLAGS=-march=armv8.2-a;-DCMAKE_Fortran_FLAGS=-march=armv8.2-a
```
The following reproducer was used:
sample.f90
```fortran
subroutine test(data)
use omp_lib
implicit none
real(4),dimension(80,100,10,500),intent(IN) :: data
real(8) t1,t2
open(10,file='test.dat',form='unformatted',access='sequential',status='unknown')
t1 = omp_get_wtime()
write(10) data
t2 = omp_get_wtime()
close(10)
write(*,'(a,1x,f8.3)') 'write',t2-t1
end subroutine test
program main
implicit none
real(4),dimension(80,100,10,500):: data
data = ""
call test(data)
end program main
```
The generated file size is approximately 160 MB.
Measurements on Grace / Neoverse-V2 with:
```console
$ export OMP_NUM_THREADS=1
$ rm test.dat ; gfortran -O2 -fopenmp -fconvert=big-endian sample.f90; ./a.out
write 0.097
$ rm test.dat flang -O2 -fopenmp -fconvert=big-endian sample.f90; ./a.out
write 0.494
```
The observed runtime ranges were:
|Compiler|Option|Time(s)|
|---|---|---|
|gfortran|-fconvert=big-endian| 0.089-0.100|
|gfortran|default| 0.076-0.101|
|flang|-fconvert=big-endian| 0.494-0.604|
|flang|default| 0.026-0.143|
Without endian conversion, flang performs similarly to or faster than gfortran for this benchmark. However, enabling `-fconvert=big-endian` introduces a much larger overhead in flang than in gfortran.
For gfortran, the impact of endian conversion appears negligible. In contrast, flang becomes approximately 5–7x slower when endian conversion is enabled.
The following perf report output was obtained from the flang executable:
```
#
#
# Total Lost Samples: 0
#
# Samples: 58 of event 'cycles:P'
# Event count (approx.): 2170426290
#
# Overhead Command Shared Object Symbol >
# ........ ....... ................ ...............................................................................>
#
25.17% a.out a.out [.] Fortran::runtime::io::ExternalFileUnit::Emit(char const*, unsigned long, un>
19.99% a.out a.out [.] Fortran::runtime::io::descr::DescriptorIoTicket<(Fortran::runtime::io::Dire>
9.82% a.out [unknown] [k] 0xffffceef7741c840
7.86% a.out libc.so.6 [.] __memcpy_generic
5.56% a.out [unknown] [k] 0xffffceef77b76298
```
The perf profile shows that a significant amount of time is spent inside the unformatted I/O runtime.
Combined with the large difference between runs with and without `-fconvert=big-endian`, endian conversion overhead appears to be one possible contributor to the observed slowdown.
I am currently investigating runtime-level optimizations and would appreciate feedback on whether this behavior is already known or if additional profiling data would be helpful.
I have a prototype runtime change that reduces the overhead of endian conversion and improves this benchmark by approximately 10%, but I would first like to understand whether this issue is already known and whether this direction is reasonable
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs