Semaphores require you to submit to GPU using vkQueueSubmit(), which is an expensive operation. Having fewer vkQueueSubmit() calls instead of too many is always going to be better.
Moreover, barriers allow for a more fine control over synchronization, giving you better optimization opportunities. vkQueueSubmit() is more suited for frame graphs where there are multiple passes that can execute in parallel and have dependencies on other passes.