Truly parallel execution of pairwise_kernels and pairwise_distances

### Describe the workflow you want to enable

Both `pairwise_kernels` and `pairwise_distances` functions call `_parallel_pairwise` function, which is (contrary to its name) not parallel as it enforces the threading backend. Therefore, these functions are terribly slow, especially for computationally expensive user-defined metrics. I understand that the reasons for the threading backend are possibly large memory demands and data communication overhead but I suggest a different approach. Also, the documentation for these functions talks about parallel execution and processes which is currently simply not true.

### Describe your proposed solution

The memory and data communication issues can be reduced by a smarter distribution of the input data to individual processes. Right now, only `Y` is sliced in the `_parallel_pairwise` function which is suboptimal for parallel processing. Both `X` and `Y` should be sliced to lower the demands for multiprocessing. For example for 100x100 `X` and `Y` distributed to 100 processes, we have to copy 100+1 inputs to every process when slicing only `Y` while only 10+10 when slicing both `X` and `Y`. As a result, multiprocessing can be allowed. Also, joblib does automatic memmapping in some cases.

Alternatively, at least the documentation for  `pairwise_kernels` and `pairwise_distances` should be corrected.

### Describe alternatives you've considered, if relevant

_No response_

### Additional context

_No response_

COMMENT:
@lesteve @ogrisel 
Hi,
I found some time to test the free-threaded version and here are the results. For the IO-bound case without setting the `OPENBLAS_NUM_THREADS` environment variable (and therefore using also the internal OPENBLAS threading):

<p float="left">
  <img src="https://github.com/user-attachments/assets/62e6c94d-d64a-4ed4-9080-8e56f41b0a68" width="400" />
  <img src="https://github.com/user-attachments/assets/6ff39aed-ce51-4c88-9276-a97fcdc63fa9" width="400" /> 
</p>

Everything, even multiprocessing was tested with the GIL turned off. None of the approaches actually accelerates the calculation in this case/setup when allowing parallelism inside the `_parallel_pairwise` function. However, if I set `OPENBLAS_NUM_THREADS=1`, I get the following results:

<p float="left">
  <img src="https://github.com/user-attachments/assets/01ed338a-bd29-4c9f-810b-93bbee90ab3e" width="400" />
  <img src="https://github.com/user-attachments/assets/6852b534-2424-422b-84cf-fa74d8ad98fb" width="400" /> 
</p>

These results correspond to the results from the regular python setup above. Interestingly, the BLAS threading can speed up single-core execution but its interplay with the parallelism used within the `_parallel_pairwise` function can actually lead to worse results.

For the CPU-bound tasks, the picture is clear, free-threading performs the same as multiprocessing or even slightly better (for numbers of CPUs for which the slicing is suboptimal) and the best times are basically the same as in my previous setup. I set `OPENBLAS_NUM_THREADS=1` but it does not play a role in this use case.

<p float="left">
  <img src="https://github.com/user-attachments/assets/03af8554-4591-4f0a-8b11-b8a7d89146da" width="400" /> 
  <img src="https://github.com/user-attachments/assets/5815af75-588c-4e25-a8b1-08575676b4a5" width="400" />
</p>

Dependencies versions in the new setup:

```
System:
    python: 3.13.0b4 | packaged by Anaconda, Inc. | experimental free-threading build (main, Jul 24 2024, 20:51:55) [GCC 11.2.0]
executable: /user/srsen/bin/anaconda3/envs/nogil/bin/python
   machine: Linux-4.18.0-348.23.1.el8_5.x86_64-x86_64-with-glibc2.28

Python dependencies:
      sklearn: 1.6.dev0
          pip: 24.1.2
   setuptools: None
        numpy: 2.1.0.dev0
        scipy: 1.15.0.dev0
       Cython: None
       pandas: None
   matplotlib: 3.10.0.dev503+gf4f40ba46f
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 20
         prefix: libscipy_openblas
       filepath: /user/srsen/bin/anaconda3/envs/nogil/lib/python3.13t/site-packages/numpy.libs/libscipy_openblas64_-99b71e71.so
        version: 0.3.27
threading_layer: pthreads
   architecture: Haswell

       user_api: blas
   internal_api: openblas
    num_threads: 20
         prefix: libscipy_openblas
       filepath: /user/srsen/bin/anaconda3/envs/nogil/lib/python3.13t/site-packages/scipy.libs/libscipy_openblas-c128ec02.so
        version: 0.3.27.dev
threading_layer: pthreads
   architecture: Haswell

       user_api: openmp
   internal_api: openmp
    num_threads: 20
         prefix: libgomp
       filepath: /user/srsen/bin/anaconda3/envs/nogil/lib/python3.13t/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
```

Labels: New Feature