Don't use "managed types" (dynamic array, ansistring, smart pointer). They all use interlocked instructions, and that slows down memory access for all threads. Even if each string/array was only used by a single thread (as you stated each thread has its own separate mem/data).
They use interlocked instructions shortly as spinlock to check the reference count. Not during the operations themselves. I don't expect this to be a very large effect.
dyn arrays indeed only on assignment of the array var, but not for elements.
AnsiStrings do check for copy on write. And (need to check the code), by the fact that even single threads occur human noticeable slowdown (compared to pchar) they may be doing that on every access to a char in them.
If he already is at the limits of his mem bandwitdth: the locked instructions affect caching. Other cores having a cacheline including the address need to reload that. So this can add into the overall bandwidth
EDIT: the slow down due to copy on write checks wouldn't be by the interlock. But they may be part of the execution, and then in threads they may cause more cache invalidates, leading to additional loads from RAM. (which may be few or many depending on exact code...)